PDA

Ver la Versión Completa : ¿Cómo puedo implementar CreateProcess con procesos multihilo?


Black_Ocean
14-05-2008, 09:03:57
Hola estimados colegas de ClubDelphi,

Estoy complicado con una rutina que estoy haciendo y ya que no se que más hacer. Ojalá me puedan echar una manito :D

Lo que necesito es que, al ejecutar un proceso, este espere a que termine completamente su ejecución, esto es, incluyendo otros hilos que genere (en pocas palabras, que soporte multihilo). Esto se da en la mayoría de los casos cuando se ejecutan desinstaladores/instaladores de aplicaciones.

Esta rutina que he logrado hacer con ayudas sólo sirve para un proceso, pero si este genera un hilo y termina su ejecución devuelve inmediato el control, a pesar de no haber terminado el segundo proceso que generó :(

He buscado en los tips de ClubDelphi y en todos los foros y ninguno soporta multihilo :(.

Este es mi código:

Win32CreateProcess(const FileName, Parameters: String; var ExitCode: DWORD; const Wait: DWORD = 0; const Hide: Boolean = False): Boolean;
var
myInfo: SHELLEXECUTEINFO;
iWaitRes: DWORD;
begin
ZeroMemory(@myInfo, SizeOf(SHELLEXECUTEINFO));
myInfo.cbSize := SizeOf(SHELLEXECUTEINFO);
myInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
myInfo.lpFile := PChar(FileName);
myInfo.lpParameters := PChar(Parameters);
if Hide then
myInfo.nShow := SW_HIDE
else
myInfo.nShow := SW_SHOWNORMAL;
ExitCode := 0;
Result := ShellExecuteEx(@myInfo);
if Result then
begin
while WaitForSingleObject(myInfo.hProcess, 100) = WAIT_TIMEOUT do
Application.ProcessMessages;

iWaitRes := WaitForSingleObject(myInfo.hProcess, 100);

if (iWaitRes = WAIT_TIMEOUT) then
begin
Result := False;
TerminateProcess(myInfo.hProcess, 0);
end;
GetExitCodeProcess(myInfo.hProcess, ExitCode);
CloseHandle(myInfo.hProcess);
end;
end;

Espero que me puedan ayudar amigos.

De antemano, Muchas gracias y cordiales saludos ;)

cHackAll
14-05-2008, 16:22:34
program Project1;

uses Windows, tlhelp32;

var
si: TStartupInfo = (cb: SizeOf(si));
pi: TProcessInformation;
hSnapshot, hProcess: Cardinal;
pe: TProcessEntry32 = (dwSize: SizeOf(pe));

begin
CreateProcess(nil, 'explorer.exe c:\windows', nil, nil, False, 0, nil, nil, si, pi);
WaitForSingleObject(pi.hProcess, INFINITE);
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32First(hSnapshot, pe) then
repeat
if pe.th32ParentProcessID = pi.dwProcessId then
begin
hProcess := OpenProcess(SYNCHRONIZE, False, pe.th32ProcessID);
if LongBool(hProcess) then
begin
WaitForSingleObject(hProcess, INFINITE);
CloseHandle(hProcess);
end;
end;
until not Process32Next(hSnapshot, pe);
CloseHandle(hSnapshot);
end.

Nota; Tal vez para abrir algunos procesos "hijos" requieras habilitar el privilegio SeDebugPrivilege de tu proceso. También es aconsejable revises el ejemplo para poder revisar a los procesos hijos de los procesos hijos (procesos nietos y bisnietos del primero).

Saludos