0

As part of my installer, I need to call out to a DBMS system and shut it down, and then later start it up. If that DBMS hangs for some reason, my installer hangs forever. I call Exec to a command that will start or stop the database, my question is:

What exactly is the definition of ewWaitUntilIdle? If my command to start/stop the database never comes back, what meets the condition of idle?

Lex Li
  • 60,503
  • 9
  • 116
  • 147
codeymccodeface
  • 372
  • 3
  • 11
  • 3
    The windows-installer tag is used for MSI based Windows Installer. Don't misuse it. – Lex Li Jul 12 '12 at 01:58
  • 1
    I'm assuming that you are executing `net start` etc. Don't do that, use the WinAPI service control functions. You can then have better control over how long you wait for the service to respond before giving up and deciding how to recover from this (eg. display error). – Miral Jul 13 '12 at 01:25

1 Answers1

1

This is exact code from Inno's sources:

procedure HandleProcessWait(ProcessHandle: THandle; const Wait: TExecWait;
  const ProcessMessagesProc: TProcedure; var ResultCode: Integer);
begin
  try
    if Wait = ewWaitUntilIdle then begin
      repeat
        ProcessMessagesProc;
      until WaitForInputIdle(ProcessHandle, 50) <> WAIT_TIMEOUT;
    end;
    if Wait = ewWaitUntilTerminated then begin
      { Wait until the process returns, but still process any messages that
        arrive. }
      repeat
        { Process any pending messages first because MsgWaitForMultipleObjects
          (called below) only returns when *new* messages arrive }
        ProcessMessagesProc;
      until MsgWaitForMultipleObjects(1, ProcessHandle, False, INFINITE, QS_ALLINPUT) <> WAIT_OBJECT_0+1;
      { Process messages once more in case MsgWaitForMultipleObjects saw the
        process terminate and new messages arrive simultaneously. (Can't leave
        unprocessed messages waiting, or a subsequent call to WaitMessage
        won't see them.) }
      ProcessMessagesProc;
    end;
    { Get the exit code. Will be set to STILL_ACTIVE if not yet available }
    if not GetExitCodeProcess(ProcessHandle, DWORD(ResultCode)) then
      ResultCode := -1;  { just in case }
  finally
    CloseHandle(ProcessHandle);
  end;
end;

As you can see ewWaitUntilIdle simply uses WaitForInputIdle function - see more here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687022%28v=vs.85%29.aspx

Slappy
  • 5,250
  • 1
  • 23
  • 29
  • What would you do in case that OP's process freeze (we can call it freeze because getting process to be idle when it starts should never take a long time) ? I'm just wondering since I've suggested OP to wait for it for some time and then kill it if doesn't become idle in that time period, but it was not taken seriously even when there's an infinite loop waiting for the idle state (I've checked that in source yesterday). – TLama Jul 13 '12 at 09:02