そこで、さまざまな構成でさまざまなsikuliスクリプトを実行できるフォームをDelphiで作成しました。私が現在取り組んでいるのは、フォームを使用するユーザーが、さまざまなsikuliスクリプトを次々に実行するように設定できるようにすることです。のように:
ステップ1:SikuliScript1とConfigFile1。ステップ2:SikuliScript2とConfigFile2。など...これはこれまでのところ私のコードです:
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行は自動的に閉じます。したがって、シェルハンドラーは、実行中のプロセスをシャットダウンするタイミングを認識しています。だから私の質問です:デルファイに伝えることは可能ですか?ハンドラーがプロセスを閉じた後、次のプロセス(Sikuliスクリプト)を実行しますか? 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;
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;
プロセスハンドルが通知されるまで待つ必要があります。たとえば、WaitForSingleObjectを呼び出します。明らかにCreateProcessは、待機できるプロセスハンドルを返します。 ShellExecuteにプロセスハンドルを返すように説得することはできませんが、より有能な兄弟ShellExecuteExがそれを行います。
ただし、私はここではCreateProcessを選択します。柔軟性と制御性が向上しますが、それほど複雑ではありません。たとえば、必要に応じてコンソールウィンドウの表示を抑制できます。
わかりました。Davidが示唆したように、これについて詳しく調べて解決しました。他の誰かに質問がある場合は、私が何をしたかを示します。
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スクリプトが次々に実行されます。
これはハックであり、それほど洗練されていませんが、必要に応じて、各行で「start/wait」を使用して、スクリプトへの呼び出しを含む* .batファイルを生成することもできます。