急救:如何同步运行一个外部程序(10分)

  • 主题发起人 主题发起人 no1
  • 开始时间 开始时间
N

no1

Unregistered / Unconfirmed
GUEST, unregistred user!
在程序执行过程中用winexec()或createprocess()调用另一个外部程序,一旦外部程序开始<br>运行,函数就得到一个返回值,有没有办法使得这个外部程序结束后才返回结果呢?<br>
 
来自amo (1999-10-25 10:35:00) &nbsp;<br>给你一个使用Createprocess的函数,它可以运行外部程序或者命令,并 <br>等待运行结束: <br>&nbsp;<br>function WinExecAndWait32(FileName:String; Visibility : integer):integer; <br>var <br>&nbsp; zAppName:array[0..512] of char; <br>&nbsp; zCurDir:array[0..255] of char; <br>&nbsp; WorkDir:String; <br>&nbsp; StartupInfo:TStartupInfo; <br>&nbsp; ProcessInfo:TProcessInformation; <br>begin <br>&nbsp; StrPCopy(zAppName,FileName); <br>&nbsp; GetDir(0,WorkDir); <br>&nbsp; StrPCopy(zCurDir,WorkDir); <br>&nbsp; FillChar(StartupInfo,Sizeof(StartupInfo),#0); <br>&nbsp; StartupInfo.cb := Sizeof(StartupInfo); <br>&nbsp; StartupInfo.dwFlags := STARTF_USESHOWWINDOW; <br>&nbsp; StartupInfo.wShowWindow := Visibility; <br>&nbsp; if not CreateProcess(nil, <br>&nbsp; &nbsp; zAppName, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ pointer to command line string } <br>&nbsp; &nbsp; nil, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { pointer to process security attributes } <br>&nbsp; &nbsp; nil, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { pointer to thread security attributes } <br>&nbsp; &nbsp; false, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { handle inheritance flag } <br>&nbsp; &nbsp; CREATE_NEW_CONSOLE or &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ creation flags } <br>&nbsp; &nbsp; NORMAL_PRIORITY_CLASS, <br>&nbsp; &nbsp; nil, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { pointer to new environment block } <br>&nbsp; &nbsp; nil, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { pointer to current directory name } <br>&nbsp; &nbsp; StartupInfo, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { pointer to STARTUPINFO } <br>&nbsp; &nbsp; ProcessInfo) then Result := -1 { pointer to PROCESS_INF } <br>&nbsp; else begin <br>&nbsp; &nbsp; WaitforSingleObject(ProcessInfo.hProcess,INFINITE); <br>&nbsp; &nbsp; GetExitCodeProcess(ProcessInfo.hProcess,Result); <br>&nbsp; end; <br>end; <br><br>&nbsp;<br>
 
GanQuan,你说的这个过程我试过了不行,如果调用的外部程序本身就是delphi编译的程序好像<br>就可以,但因为我调用的外部程序是个install shield做的安装程序,试过以后程序会死锁,<br>是什么原因呢,还有没有别的办法
 
Function tform1.WinExecAndWait32V2( FileName: String; Visibility: integer ): DWORD;<br>&nbsp; Procedure WaitFor( processHandle: THandle );<br>&nbsp; &nbsp; Var<br>&nbsp; &nbsp; &nbsp; msg: TMsg;<br>&nbsp; &nbsp; &nbsp; ret: DWORD;<br>&nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; Repeat<br>&nbsp; &nbsp; &nbsp; &nbsp; ret := MsgWaitForMultipleObjects(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1, { 1 handle to wait on }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;processHandle, { the handle }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;False, { wake on any event }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INFINITE, { wait without timeout }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;QS_PAINT or { wake on paint messages }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;QS_SENDMESSAGE { or messages from other threads }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;);<br>&nbsp; &nbsp; &nbsp; &nbsp; If ret = WAIT_FAILED Then Exit; { can do little here }<br>&nbsp; &nbsp; &nbsp; &nbsp; If ret = (WAIT_OBJECT_0 + 1) Then Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Woke on a message, process paint messages only. Calling<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PeekMessage gets messages send from other threads processed. }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; While PeekMessage( msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE ) Do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DispatchMessage( msg );<br>&nbsp; &nbsp; &nbsp; &nbsp; End;<br>&nbsp; &nbsp; &nbsp; Until ret = WAIT_OBJECT_0;<br>&nbsp; &nbsp; End; { Waitfor }<br>&nbsp; Var { V1 by Pat Ritchey, V2 by P.Below }<br>&nbsp; &nbsp; zAppName:array[0..512] of char;<br>&nbsp; &nbsp; StartupInfo:TStartupInfo;<br>&nbsp; &nbsp; ProcessInfo:TProcessInformation;<br>&nbsp; Begin { WinExecAndWait32V2 }<br>&nbsp; &nbsp; StrPCopy(zAppName,FileName);<br>&nbsp; &nbsp; FillChar(StartupInfo,Sizeof(StartupInfo),#0);<br>&nbsp; &nbsp; StartupInfo.cb := Sizeof(StartupInfo);<br>&nbsp; &nbsp; StartupInfo.dwFlags := STARTF_USESHOWWINDOW;<br>&nbsp; &nbsp; StartupInfo.wShowWindow := Visibility;<br>&nbsp; &nbsp; If not CreateProcess(nil,<br>&nbsp; &nbsp; &nbsp; zAppName, { pointer to command line string }<br>&nbsp; &nbsp; &nbsp; nil, { pointer to process security attributes }<br>&nbsp; &nbsp; &nbsp; nil, { pointer to thread security attributes }<br>&nbsp; &nbsp; &nbsp; false, { handle inheritance flag }<br>&nbsp; &nbsp; &nbsp; CREATE_NEW_CONSOLE or { creation flags }<br>&nbsp; &nbsp; &nbsp; NORMAL_PRIORITY_CLASS,<br>&nbsp; &nbsp; &nbsp; nil, { pointer to new environment block }<br>&nbsp; &nbsp; &nbsp; nil, { pointer to current directory name }<br>&nbsp; &nbsp; &nbsp; StartupInfo, { pointer to STARTUPINFO }<br>&nbsp; &nbsp; &nbsp; ProcessInfo) { pointer to PROCESS_INF }<br>&nbsp; &nbsp; Then<br>&nbsp; &nbsp; &nbsp; Result := DWORD(-1) { failed, GetLastError has error code }<br>&nbsp; &nbsp; Else Begin<br>&nbsp; &nbsp; &nbsp; &nbsp;Waitfor(ProcessInfo.hProcess);<br>&nbsp; &nbsp; &nbsp; &nbsp;GetExitCodeProcess(ProcessInfo.hProcess, Result);<br>&nbsp; &nbsp; &nbsp; &nbsp;CloseHandle( ProcessInfo.hProcess );<br>&nbsp; &nbsp; &nbsp; &nbsp;CloseHandle( ProcessInfo.hThread );<br>&nbsp; &nbsp; End; { Else }<br>&nbsp; End; { WinExecAndWait32V2 }<br>
 
用CreateProcess运行<br>用WaitForSingleObject等运行完毕<br>用GetExitCodeProcess得到的进程退出值<br>为0表示成功,不为0就是失败
 
后退
顶部