transporte tierra procesos internos geologicos externos exogenos erosion endogenos agentes delphi winapi

delphi - tierra - ¿Cómo puedo esperar hasta que se complete un proceso externo?



procesos geologicos internos (4)

Con CreateProcess puede obtener un identificador de proceso y con WaitForSingleObject puede verificar cuándo se completa el proceso. Utilizo la siguiente función, esto ejecuta el comando en segundo plano:

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;

Así que hice un formulario en Delphi que me permite ejecutar varios scripts sikuli con varias configuraciones. Lo que estoy trabajando ahora es hacer posible que alguien use el formulario, para configurar varios scripts de sikuli para que se ejecuten uno tras otro. Como en:

Paso 1: SikuliScript1 con ConfigFile1. Paso 2: SikuliScript2 con ConfigFile2. etc ... Este es mi código hasta ahora:

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;

Y esto funciona perfecto, la secuencia de comandos de sikuli se ejecuta perfectamente, y mientras se ejecuta, la línea de cmd es visible con las diversas acciones que se muestran que se están realizando. Después de que la secuencia de comandos de sikuli está lista, la línea de cmd se cierra por sí misma. Entonces, el manejador de shell sabe cuándo cerrar el proceso en ejecución. Entonces mi pregunta es: ¿es posible decir delphi: después de que el controlador haya cerrado el proceso, ejecute el siguiente proceso (Sikuli Script)? Ahora sé que puedo ir con todo el createProcess en Delphi, pero parece excesivo. Tiene que haber una forma de hacerlo más rápido y más fácil. Alguien tiene una pista?


Debe esperar hasta que se indique el identificador del proceso. Por ejemplo, mediante una llamada a WaitForSingleObject. Obviamente, CreateProcess le devuelve un identificador de proceso en el que puede esperar. No puede convencer a ShellExecute de que devuelva un identificador de proceso, pero su hermano más capaz, ShellExecuteEx, lo hará.

Sin embargo, yo personalmente elegiría CreateProcess aquí. Obtendrá más flexibilidad y control, y no es tan complejo. Por ejemplo, puede suprimir la visualización de la ventana de la consola si lo desea.


Este es un truco y es menos sofisticado, pero tal vez podrías generar un archivo * .bat que contenga las llamadas a los guiones, si es necesario usando "iniciar / esperar" en cada línea.


Ok, he investigado más sobre esto y lo he resuelto, tal como sugirió David. Mostraré lo que hice, si alguien más tiene alguna pregunta o algo:

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;

Funciona exactamente como yo quería. Los 2 scripts de sikuli se ejecutarán uno tras otro.