外部アプリケーションを実行したいと仮定して、指定された時間その終了を待ち、それ自体が終了しない場合は、セットアップからそれを強制終了します。次のコードを試してください。ここで使用される魔法の定数に対して、WaitForSingleObject
関数のパラメーターとして使用される3000は、セットアップがプロセスの終了を待機する時間(ミリ秒単位)です。その時間内にそれ自体で終了しない場合は、TerminateProcess
関数によって強制終了されます。ここで、666の値はプロセスの終了コードです(この場合はかなり悪です:-)
[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 'WaitForSingleObject@kernel32.dll stdcall';
function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL;
external 'TerminateProcess@kernel32.dll 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;
私がWindows7のInnoSetup5.4.3 UnicodeおよびANSIバージョンでテストしたコード(からのWindows API関数宣言に条件付き定義を使用するという彼のアイデアに感謝しますthis post
)