所以我在Delphi中创建了一个表单,允许我运行各种配置的各种sikuli脚本。我现在正在做的是让使用该表单的人可以设置各种sikuli脚本以便一个接一个地运行。如:
步骤1:带ConfigFile1的SikuliScript1。 第2步:使用ConfigFile2的SikuliScript2。 等等... 到目前为止,这是我的代码:
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;
这很完美,sikuli脚本运行完美,并且在运行时,cmd线可以看到正在执行的各种动作。 sikuli脚本完成后,cmd行自行关闭。因此shell处理程序知道何时关闭正在运行的进程。所以我的问题是:是否有可能告诉delphi:在处理程序关闭进程后,运行下一个进程(Sikuli脚本)? 现在我知道我可以在delphi中使用整个createProcess,但它似乎有点矫枉过正。必须有一种方法来更快更容易地做到这一点。 任何人都有线索?
答案 0 :(得分:23)
使用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;
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;
答案 1 :(得分:6)
您需要等到处理过程句柄发出信号。例如,通过调用WaitForSingleObject。显然,CreateProcess会返回一个您可以等待的进程句柄。你不能说服ShellExecute返回一个进程句柄,但它更有能力的兄弟ShellExecuteEx会这样做。
但是,我个人会在这里选择CreateProcess。您将获得更多的灵活性和控制力,而且并不复杂。例如,您可以根据需要禁止显示控制台窗口。
答案 2 :(得分:1)
好的,我已经对此进行了更多的研究并解决了它,就像大卫建议的那样。我会展示我的所作所为,如果其他人有任何问题或其他任何问题:
procedure TSikRunForm.btnRunClick(Sender: TObject);
begin
CmdLine:= 'C:\\windows\\system32\\cmd.exe';
uniqueString(CmdLine);
if SikFound then begin
//----------For loop---------------
DirScript:= TScriptEdit.Text;
DirConfig:= TConfEdit.Text;
DirCombo:= '/C '+DirSik+'\sikuli-script.cmd' +' -r ' + DirScript + ' --args '+DirConfig;
CreateProcess(PChar(CmdLine),PChar(DirCombo),Nil,Nil,False,CREATE_NO_WINDOW,nil,nil,StartInfo,ProcInfo);
procHandle:= ProcInfo.hProcess;
Application.minimize;
WaitForSingleObject(procHandle, INFINITE);
DirScript:= TScriptEdit2.Text;
DirConfig:= TConfEdit2.Text;
DirCombo:= '/C '+DirSik+'\sikuli-script.cmd' +' -r ' + DirScript + ' --args '+DirConfig;
CreateProcess(PChar(CmdLine),PChar(DirCombo),Nil,Nil,False,CREATE_NO_WINDOW,nil,nil,StartInfo,ProcInfo);
procHandle:= ProcInfo.hProcess;
Application.minimize;
WaitForSingleObject(procHandle, INFINITE);
//----------------------------------------
showMessage('Gedoan');
end else begin
ShowMessage('Select the correct folder for your Sikuli installation folder');
end;
end;
完全符合我的要求。 2个sikuli脚本将一个接一个地运行。
答案 3 :(得分:0)
这是一种不太复杂的黑客攻击方式,但也许你可以生成一个* .bat文件,其中包含对脚本的调用,必要时在每一行使用“start / wait”。