如何等待外部程序完成? [英] How can I wait until an external process has completed?

查看:241
本文介绍了如何等待外部程序完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在Delphi中制作了一个表单,让我可以用各种配置来运行各种sikuli脚本。我现在正在做的是让使用表单的人可以设置各种各样的sikuli脚本来运行。如下:



步骤1:SikuliScript1与ConfigFile1。
步骤2:SikuliScript2与ConfigFile2。
etc ...
这是我的代码到目前为止:

 程序TSikRunForm.btnRunClick(发件人: TObject); 
begin
DirCombo:='/ C'+ DirSik +'\sikuli-script.cmd'+'-r'+ DirScript +'--args'+ DirConfig;
如果SikFound然后开始
ShellExecute(Handle,nil,'cmd.exe',pChar(DirCombo),nil,SW_SHOWNORMAL);
Application.minimize;
end else begin
ShowMessage('为您的Sikuli安装文件夹选择正确的文件夹');
结束
结束

这样做完美,sikuli脚本运行完美,而在运行时,cmd行可见显示的各种动作正在执行。 sikuli脚本完成后,cmd行自行关闭。所以shell处理程序知道什么时候关闭正在运行的进程。所以我的问题是:是否可以告诉delphi:处理程序关闭进程后,运行下一个进程(Sikuli Script)?
现在我知道我可以在delphi中使用整个createProcess,但是它似乎是过度的杀伤力。必须有一种方法可以更快更容易地做到这一点。
任何人都有一个线索?

解决方案

使用CreateProcess可以获得一个进程句柄,使用WaitForSingleObject可以检查何时过程完成。
我使用以下函数,这在后台运行命令:

  procedure ExecuteAndWait(const aCommando:string) ; 
var
tmpStartupInfo:TStartupInfo;
tmpProcessInformation:TProcessInformation;
tmpProgram:String;
begin
tmpProgram:= trim(aCommando);
FillChar(tmpStartupInfo,SizeOf(tmpStartupInfo),0);
with tmpStartupInfo do
begin
cb:= SizeOf(TStartupInfo);
wShowWindow:= SW_HIDE;
结束

如果CreateProcess(nil,pchar(tmpProgram),nil,nil,true,CREATE_NO_WINDOW,
nil,nil,tmpStartupInfo,tmpProcessInformation)然后
begin
//循环每10 ms
,而WaitForSingleObject(tmpProcessInformation.hProcess,10)> 0 do
begin
Application.ProcessMessages;
结束
CloseHandle(tmpProcessInformation.hProcess);
CloseHandle(tmpProcessInformation.hThread);
end
else
begin
RaiseLastOSError;
结束
结束


So I have made a form in Delphi that allows me to run various sikuli scripts with various configurations. What I am working on now is to make it possible for someone using the form, to set up various sikuli scripts to run on after another. As in:

Step 1: SikuliScript1 with ConfigFile1. Step 2: SikuliScript2 with ConfigFile2. etc... This is my code so far:

procedure TSikRunForm.btnRunClick(Sender: TObject);
begin
    DirCombo:= '/C '+DirSik+'\sikuli-script.cmd' +' -r ' + DirScript + ' --args '+DirConfig;
    if SikFound then begin
      ShellExecute(Handle, nil, 'cmd.exe', pChar(DirCombo), nil, SW_SHOWNORMAL);
      Application.minimize;
    end else begin
      ShowMessage('Select the correct folder for your Sikuli installation folder');
    end;
end;

And this works perfect, the sikuli script runs perfectly, and while running, the cmd line is visible with the various actions shown that are being performed. After the sikuli script is done, the cmd line closes on its own. So the shell handler knows when to shut down the running process. So my question is: Is it possible to tell delphi: After the handler has shut the process, run the next process (Sikuli Script)? Now I know I can go with the whole createProcess in delphi, but it just seems overkill. There has got to be a way to do this faster and easier. Anyone have a clue?

解决方案

With CreateProcess you can get a process handle and with WaitForSingleObject you can check when the process is complete. I use the following function, this runs the command in the background:

procedure ExecuteAndWait(const aCommando: string);
var
  tmpStartupInfo: TStartupInfo;
  tmpProcessInformation: TProcessInformation;
  tmpProgram: String;
begin
  tmpProgram := trim(aCommando);
  FillChar(tmpStartupInfo, SizeOf(tmpStartupInfo), 0);
  with tmpStartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    wShowWindow := SW_HIDE;
  end;

  if CreateProcess(nil, pchar(tmpProgram), nil, nil, true, CREATE_NO_WINDOW,
    nil, nil, tmpStartupInfo, tmpProcessInformation) then
  begin
    // loop every 10 ms
    while WaitForSingleObject(tmpProcessInformation.hProcess, 10) > 0 do
    begin
      Application.ProcessMessages;
    end;
    CloseHandle(tmpProcessInformation.hProcess);
    CloseHandle(tmpProcessInformation.hThread);
  end
  else
  begin
    RaiseLastOSError;
  end;
end;

这篇关于如何等待外部程序完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆