Вопрос по – Inno Setup Exec () функция Ожидание в течение ограниченного времени

5

В моем скрипте Inno Setup я выполняю сторонний исполняемый файл. Я используюExec() функция как ниже:

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

УпоминаяewWaitUntilTerminated он ждет, покаSomeExe.exe не выходит. Я хочу ждать только 10 секунд.

Есть ли решение для этого?

Может он хочет убить процесс? Я полагаю, вы могли бы выполнить его нормально и создать простой таймер, который убивает процесс через 10 секунд. Slappy
И что ты будешь делать через 10 секунд? TLama
@ Сладкий, вы можете использовать, например,Sleep функция, а затем убить процесс. Проблема в том, что вы не знаете, какой процесс и насколько я знаю, из доступных функций InnoSetup никто не возвращает дескриптор выполненного процесса, который вам нужен для завершения процесса. И если бы вы знали дескриптор процесса, лучше использоватьWaitForSingleObject функция ожидания. Ниже приведен пример кода. TLama

Ваш Ответ

1   ответ
7

Предполагая, что вы хотите выполнить внешнее приложение, ожидая его завершения в течение определенного времени и, если оно не завершается само по себе, убивая его из программы установки, попробуйте следующий код. Для магических констант, используемых здесь, 3000 используется в качестве параметра вWaitForSingleObject Функция - это время в миллисекундах, в течение которого установка будет ждать завершения процесса. Если он не завершается в это время сам по себе, он уничтожается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 '[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;

Код, который я тестировал с Inno Setup 5.4.3 Unicode и версией ANSI в Windows 7 (спасибо Кобику за его идею использовать условные определения для объявлений функций Windows API отthis post)

Это хорошее решение!

Похожие вопросы