delphi执行外部程序等待程序运行成功,而不是程序退出,该如何解决
delphi执行外部程序等待程序运行成功,而不是程序退出
我想用delphi执行一个外部程序,等外部程序完全运行(这个程序不能关闭),并取得这个外部程序中的Edit句柄
在主程序运行的时候需要外部程序辅助,我现在用CreateProcess运行程序以后,因为程序太快edit句柄有时取不到,如何等待,这个外部程序完全打开了,再往下读句柄
------解决方案--------------------
function WinExecAndWait32(FileName: string; Visibility: integer): Dword;
{执行一个外部程序并等待其结束}
var
zAppName: array[0..512] of char;
zCurDir: array[0..255] of char;
WorkDir: string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
chmForm.btSaveas.Tag := 1;
chmForm.btView.Tag := 1;
TRY
StrPCopy(zAppName, FileName);
GetDir(0, WorkDir);
StrPCopy(zCurDir, WorkDir);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil,
zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags } NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo)
then Result := 1 { pointer to PROCESS_INF }
else
begin
while WaitforSingleObject(ProcessInfo.hProcess, 10) = WAIT_TIMEOUT
do Application.ProcessMessages;
GetExitCodeProcess(ProcessInfo.hProcess, Result);
end;
FINALLY
chmForm.btSaveas.Tag := 0;
chmForm.btView.Tag := 0;
END;
end;
------解决方案--------------------
调用如:
WinexecAndWait32(‘arj.exe >c:\temp\arj.txt‘,SW_SHOW);
------解决方案--------------------
其实可以变化一下,等几秒然后再读,不需要等到运行成功,一般5秒钟足够程序运行完毕了
------解决方案--------------------
WaitForInputIdle
------解决方案--------------------
------解决方案--------------------
标记
------解决方案--------------------
------解决方案--------------------
CreateProcess
PostMessage(AppHandle,WM_CLOSE,NULL,NULL);
WaitForSingleObject
------解决方案--------------------
我想用delphi执行一个外部程序,等外部程序完全运行(这个程序不能关闭),并取得这个外部程序中的Edit句柄
在主程序运行的时候需要外部程序辅助,我现在用CreateProcess运行程序以后,因为程序太快edit句柄有时取不到,如何等待,这个外部程序完全打开了,再往下读句柄
------解决方案--------------------
function WinExecAndWait32(FileName: string; Visibility: integer): Dword;
{执行一个外部程序并等待其结束}
var
zAppName: array[0..512] of char;
zCurDir: array[0..255] of char;
WorkDir: string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
chmForm.btSaveas.Tag := 1;
chmForm.btView.Tag := 1;
TRY
StrPCopy(zAppName, FileName);
GetDir(0, WorkDir);
StrPCopy(zCurDir, WorkDir);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil,
zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags } NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo)
then Result := 1 { pointer to PROCESS_INF }
else
begin
while WaitforSingleObject(ProcessInfo.hProcess, 10) = WAIT_TIMEOUT
do Application.ProcessMessages;
GetExitCodeProcess(ProcessInfo.hProcess, Result);
end;
FINALLY
chmForm.btSaveas.Tag := 0;
chmForm.btView.Tag := 0;
END;
end;
------解决方案--------------------
调用如:
WinexecAndWait32(‘arj.exe >c:\temp\arj.txt‘,SW_SHOW);
------解决方案--------------------
其实可以变化一下,等几秒然后再读,不需要等到运行成功,一般5秒钟足够程序运行完毕了
------解决方案--------------------
WaitForInputIdle
------解决方案--------------------
------解决方案--------------------
标记
------解决方案--------------------
------解决方案--------------------
CreateProcess
PostMessage(AppHandle,WM_CLOSE,NULL,NULL);
WaitForSingleObject
------解决方案--------------------
- Delphi(Pascal) code
function ExeProc(fun:Pointer;para:array of const):Cardinal; const//先EAX、EDX、ECX,后堆栈 RecSize=SizeOf(TVarRec);// 循环处理参数列表时递增的字节数 var cnt:Integer; begin cnt:=Length(para);// 获取参数个数 asm PUSH ESI // 保存 ESI MOV ESI, para // ESI 指向参数表首址 CMP cnt, 1 // 判断参数个数 JB @np JE @1p CMP cnt, 3 JB @2p JE @3p CLD // 清空方向标志 MOV ECX, cnt // 循环cnt - 3次 SUB ECX,3 MOV EDX, RecSize*3 //跳过3个参数 @LP: PUSH [ESI][EDX] //基址变址 参数进栈 ADD EDX, RecSize LOOP @LP @3p: MOV ECX, [ESI] + RecSize*2 @2p: MOV EDX, [ESI] + RecSize @1p: MOV EAX, [ESI] @np: CALL fun MOV Result, EAX // 返回值 POP ESI end; end; function waitFor(fun:Pointer;para:array of const;ms:Integer=-1): Boolean; var b:boolean; n:Cardinal; begin Result:=False; b:=ms=-1; n:=GetTickCount; while ((GetTickCount-n)<=ms)or(b) do begin if Boolean(ExeProc(fun,para)) then begin Result:=True; Exit; end; Application.ProcessMessages; end; end; eg. function findWin(s:string):Boolean; begin Result:= Findwindow(PChar(s),nil)<>0; end; procedure TForm1.FormCreate(Sender: TObject); begin if waitFor(@Findwin,['Notepad']) then MessageDlg('', mtWarning, [mbOK], 0); end;