2012-06-05 17 views
5

Nel mio script Inno Setup eseguo un eseguibile di terze parti. Sto usando la funzione Exec() come di seguito:Funzione Inno Setup Exec() Attendi un tempo limitato

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

Menzionando ewWaitUntilTerminated si attende che il SomeExe.exe non si chiude. Voglio aspettare solo 10 secondi.

Esiste una soluzione?

+0

E cosa farai dopo quei 10 secondi? – TLama

+0

Forse vuole uccidere il processo? Suppongo che potresti eseguirlo normalmente e creare un semplice timer che uccide il processo dopo 10 secondi. – Slappy

+0

@Slappy, è possibile utilizzare ad es. ['Sleep'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx) funzione e quindi uccidere il processo. Il problema è che non si conosce il processo e, per quanto ne so, dalle funzioni disponibili di InnoSetup nessuno restituisce l'handle del processo eseguito, che è necessario per la terminazione del processo. E se vuoi sapere come gestire il processo, è meglio usare ['WaitForSingleObject'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29. aspx) funzione per l'attesa. Vedi sotto per un esempio di codice. – TLama

risposta

7

Supponendo che si desideri eseguire un'applicazione esterna, in attesa della sua terminazione per un periodo di tempo specificato e se non viene terminata da sola, eliminandola dall'installazione, provare il seguente codice. Per le costanti magiche qui usate, 3000 usato come parametro nella funzione WaitForSingleObject è il tempo in millisecondi per quanto tempo l'installazione attenderà che il processo termini. Se non termina in quel tempo per sé, viene ucciso dalla funzione TerminateProcess, dove il valore 666 è il codice di uscita del processo (piuttosto male in questo 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; 

Il codice che ho testato con Inno Setup 5.4.3 Versione Unicode e ANSI su Windows 7 (grazie a kobik per la sua idea di usare condizionali definisce dichiarazioni di funzioni API Windows da this post)

+0

Questa è una bella soluzione! – GTAVLover

Problemi correlati