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
[解决办法]
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);beginif waitFor(@Findwin,['Notepad']) then MessageDlg('', mtWarning, [mbOK], 0);end;