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
)
E cosa farai dopo quei 10 secondi? – TLama
Forse vuole uccidere il processo? Suppongo che potresti eseguirlo normalmente e creare un semplice timer che uccide il processo dopo 10 secondi. – Slappy
@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