Тема: WinExec32AndWait

В связи с повышенным интересом к "ожиданию завершения работы внешнего приложения" и затяжным молчанием тех, кто знает как это реализовывается привожу вариант функции WinExec32AndWait.
Я вообще в WinApi слабоват и поэтому полазил по Инету в поисках этой функции, нашел несколько вариантов, объединил их в один (как мне показалось более приемлимый и понятный), добавил немного коментариев к уже имеющимся и привожу что получилось.
Функция работает. Проверил сделав COM-сервер в DLL и обратившись к нему из Lisp-а.

function WinExec32AndWait(FileName : String) : Boolean;
var
  si : TStartupInfo;
  pi : TProcessInformation;
begin
  ZeroMemory(@si,sizeof(si));
  si.cb := SizeOf(si);
  if not CreateProcess(
    nil,
    PChar(FileName),   // указатель командной строки
    nil,               // указатель на процесс атрибутов безопасности
    nil,               // указатель на поток атрибутов безопасности
    False,             // флаг родительского обработчика
    0,                 // флаг создания
    nil,               // указатель на новую среду процесса
    nil,               // указатель на имя текущей директории
    si,                // указатель на StartupInfo
    pi)                // указатель на ProcessInformation
    then
      Result := False  // если не удалось запустить процесс
    else
      begin
        // ожидаем завершение процесса (INFINITE -> время ожидания неопределено)
        If WaitForSingleObject(pi.hProcess, INFINITE) = WAIT_FAILED
          then Result := False  // если подождать не удалось
          else Result := True;  // если подождать удалось
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
      end;
end;

Я не претендую на правильность и истинность этой функции. Просто, может быть кому пригодится или кто-то подправит и т.д.
Вообще, давайте в этой ветке создадим тему типа "Делимся находками" и будем делиться. Если кто поддержит, то я тему создам. А то все ходят кривотолки - "можно так, можно эдак". Давайте действовать, товарищи.
P.S. Хотя может я один такой дурак.

Re: WinExec32AndWait

unit JclMiscel;
Из Jedi Code Library

function WinExec32AndWait(const Cmd: string; const CmdShow: Integer): Cardinal;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  Result := Cardinal($FFFFFFFF);
  FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := CmdShow;
  if CreateProcess(nil, PChar(Cmd), nil, nil, False, NORMAL_PRIORITY_CLASS,
    nil, nil, StartupInfo, ProcessInfo) then
  begin
    WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
    if WaitForSingleObject(ProcessInfo.hProcess, INFINITE) = WAIT_OBJECT_0 then
    begin
      if not GetExitCodeProcess(ProcessInfo.hProcess, Result) then
        Result := Cardinal($FFFFFFFF);
    end;
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
  end;
end;

Естественно, вариантов подобной функции множество. Все отличаются степенью ненадежности - обычно автор делает для себя, иногда не зная нюансов, с которыми не сталкивался.
Конечно, можно самому придумать отличное решение, но вероятность того, что код из библиотеки, проверенной десятками тысяч программистов, более надежен - выше.
Свои функции лучше именовать уникально (с префиксами). Особенно с явно напрашивающимися именами, иначе возможны конфликты.