2012-06-05 6 views
5

In meinem Inno Setup-Skript ausführe ich ausführbare Drittpartei. Ich bin mit der Exec() Funktion wie folgt:Inno Setup Exec() - Funktion Warte auf eine begrenzte Zeit

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

von ewWaitUntilTerminated erwähnt es wartet, bis die SomeExe.exe nicht beendet. Ich möchte nur 10 Sekunden warten.

Gibt es eine Lösung dafür?

+0

Und was werden Sie nach diesen 10 Sekunden tun? – TLama

+0

Vielleicht will er den Prozess töten? Ich nehme an, du könntest es normal ausführen und einen einfachen Timer erstellen, der den Prozess nach 10 Sekunden abbricht. – Slappy

+0

@Slamy, könnten Sie z.B. [Schlaf] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx) Funktion und dann den Prozess beenden. Das Problem ist, dass Sie nicht wissen, welcher Prozess und soweit ich weiß, niemand von den verfügbaren InnoSetup-Funktionen ausgeführte Prozesshandle zurückgibt, die Sie für die Prozessbeendigung benötigen. Und wenn Sie das Prozess-Handle kennen würden, ist es besser, das ['WaitForSingleObject'' zu verwenden (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29. aspx) -Funktion zum Warten. Siehe unten für ein Codebeispiel. – TLama

Antwort

7

Angenommen, Sie möchten eine externe Anwendung ausführen, die für eine bestimmte Zeit auf ihre Beendigung wartet, und wenn sie nicht selbst beendet wird, indem Sie sie aus dem Setup löschen, versuchen Sie den folgenden Code. Für die hier verwendeten magischen Konstanten ist 3000 als Parameter in der WaitForSingleObject-Funktion die Zeit in Millisekunden, in der das Setup auf die Beendigung des Prozesses wartet. Wenn sie nicht von selbst in dieser Zeit nicht beenden, wird es durch die TerminateProcess Funktion getötet, wo der 666 Wert der Prozess-Exit-Code ist (ganz böse in diesem Fall :-)

[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; 

Der Code ich habe getestet mit Inno Setup 5.4.3 Unicode und ANSI-Version unter Windows 7 (Danke an Kobik für seine Idee, bedingte Definitionen für Windows-API-Funktionsdeklarationen von this post)

+0

Dies ist eine nette Lösung! – GTAVLover