2012-06-05 19 views
5

En mi script Inno Setup estoy ejecutando un ejecutable de terceros. Estoy utilizando la función Exec() de la siguiente manera:Función Inno Setup Exec() Espere por un tiempo limitado

Exec(ExpandConstant('{app}\SomeExe.exe'), '', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode); 

Al mencionar ewWaitUntilTerminated espera hasta que el SomeExe.exe no se cierra. Quiero esperar solo por 10 segundos.

¿Hay alguna solución para eso?

+0

¿Y qué harás después de esos 10 segundos? – TLama

+0

¿Tal vez quiere matar el proceso? Supongo que podrías ejecutarlo normalmente y crear un temporizador simple que mate el proceso después de 10 segundos. – Slappy

+0

@Slappy, podría usar, p. ['Sleep'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx) funcionan y luego cancelan el proceso. El problema es que no sabe qué proceso y, hasta donde yo sé, de las funciones disponibles de InnoSetup nadie devuelve el identificador del proceso ejecutado, que necesita para la terminación del proceso. Y si conoce el control del proceso, es mejor usar el ['WaitForSingleObject'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29. función aspx) para esperar. Vea a continuación una muestra de código. – TLama

Respuesta

7

Suponiendo que desea ejecutar la aplicación externa, esperando su finalización durante un tiempo específico y si no termina por sí solo matando desde la configuración intente el siguiente código. Para las constantes mágicas utilizadas aquí, 3000 utilizado como el parámetro en la función WaitForSingleObject es el tiempo en milisegundos de cuánto tiempo esperará la instalación para que finalice el proceso. Si no termina en ese momento por sí mismo, es matado por la función TerminateProcess, donde el valor 666 es el código de salida del proceso (bastante mal en este caso :-)

[Code] 
#IFDEF UNICODE 
    #DEFINE AW "W" 
#ELSE 
    #DEFINE AW "A" 
#ENDIF 

const 
    WAIT_TIMEOUT = $00000102; 
    SEE_MASK_NOCLOSEPROCESS = $00000040; 

type 
    TShellExecuteInfo = record 
    cbSize: DWORD; 
    fMask: Cardinal; 
    Wnd: HWND; 
    lpVerb: string; 
    lpFile: string; 
    lpParameters: string; 
    lpDirectory: string; 
    nShow: Integer; 
    hInstApp: THandle;  
    lpIDList: DWORD; 
    lpClass: string; 
    hkeyClass: THandle; 
    dwHotKey: DWORD; 
    hMonitor: THandle; 
    hProcess: THandle; 
    end; 

function ShellExecuteEx(var lpExecInfo: TShellExecuteInfo): BOOL; 
    external 'ShellExecuteEx{#AW}@shell32.dll stdcall'; 
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; 
    external '[email protected] stdcall'; 
function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL; 
    external '[email protected] stdcall'; 

function NextButtonClick(CurPageID: Integer): Boolean; 
var 
    ExecInfo: TShellExecuteInfo; 
begin 
    Result := True; 

    if CurPageID = wpWelcome then 
    begin 
    ExecInfo.cbSize := SizeOf(ExecInfo); 
    ExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS; 
    ExecInfo.Wnd := 0; 
    ExecInfo.lpFile := 'calc.exe'; 
    ExecInfo.nShow := SW_HIDE; 

    if ShellExecuteEx(ExecInfo) then 
    begin 
     if WaitForSingleObject(ExecInfo.hProcess, 3000) = WAIT_TIMEOUT then 
     begin 
     TerminateProcess(ExecInfo.hProcess, 666); 
     MsgBox('You just killed a little kitty!', mbError, MB_OK); 
     end 
     else 
     MsgBox('The process was terminated in time!', mbInformation, MB_OK); 
    end; 
    end; 
end; 

El código que he probado con Inno Setup 5.4.3 Versión Unicode y ANSI en Windows 7 (gracias a kobik por su idea de usar declaraciones condicionales para las declaraciones de funciones API de Windows desde this post)

+0

¡Esta es una buena solución! – GTAVLover

Cuestiones relacionadas