等待执行ShellExecute吗?

| 我有一个希望很快问到的问题:是否有可能稍微延迟ShellExecute的执行? 我有一个带有autoupdater的应用程序。下载所有必需的文件等后,它将当前文件重命名为* .OLD,并将新文件重命名为以前的文件。很简单。但是然后我需要删除那些.OLD文件。此“清理”过程在MainForm.OnActivate上执行(并检查它是否是第一个激活过程)。但这显然发生得太快了(我从DeleteFile中得到False)。步骤如下:
procedure TUpdateForm.OKBtnClick(Sender: TObject);
const SHELL = \'ping 127.0.0.1 -n 2\';
begin
  ShellExecute(0,\'open\',pchar(SHELL+#13+Application.ExeName),nil,nil,SW_SHOWNORMAL);
  Application.Terminate;
end;
该过程应该重新启动应用程序。我确信删除问题是由第二个应用程序的快速启动引起的,因为如果我自己重新启动它,花一点时间,文件将被正常删除。 tl; dr版本:我需要调用ShellExecute()稍等片刻(约0.1秒),然后执行命令。 注意 我尝试使用-ping命令来尝试延迟它,但是它不起作用。 提前非常感谢你 编辑:改写 我需要这种情况||第一个应用程序关闭;等待100毫秒;第二个应用程序打开||。我需要先调用ShellExecute,然后等到调用应用程序完全关闭自身,然后再执行Shell(即打开第二个应用程序)     
已邀请:
您正在执行自动修补程序吗? 我遇到了同样的问题,这就是我绕过的问题: 您使用参数\“-delay \”或类似的名称运行第二个应用程序。 第二个应用程序处理参数\“-delay \”并休眠100 ms,然后继续正常运行。     
这个例程是我们游戏引擎中的一些utils代码。它可以运行可执行文件,并有选择地等待其退出。它将返回其退出代码:
function TSvUtils.FileExecute(ahWnd: Cardinal; const aFileName, aParams, aStartDir: string; aShowCmd: Integer; aWait: Boolean): Integer;
var
  Info: TShellExecuteInfo;
  ExitCode: DWORD;
begin

  Result := -1;
  FillChar(Info, SizeOf(Info), 0);
  Info.cbSize := SizeOf(TShellExecuteInfo);
  with Info do begin
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := ahWnd;
    lpFile := PChar(aFileName);
    lpParameters := PChar(aParams);
    lpDirectory := PChar(aStartDir);
    nShow := aShowCmd;
  end;

  if ShellExecuteEx(@Info) then
  begin
    if aWait then
    begin
      repeat
        Sleep(1);
        Application.ProcessMessages;
        GetExitCodeProcess(Info.hProcess, ExitCode);
      until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
      CloseHandle(Info.hProcess);
      Result := ExitCode;
    end;
  end
end;
这是一些可以检查进程是否存在的代码。所以...当前应用调用更新程序并终止。更新程序可以检查旧应用程序是否已终止并执行其操作(重命名,更新,删除等):
function TSvUtils.ProcessExists(const aExeFileName: string; aBringToForgound: Boolean=False): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin

  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(aExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(aExeFileName))) then
    begin
      if aBringToForgound then
        EnumWindows(@BringToForgroundEnumProcess, FProcessEntry32.th32ProcessID);
      Result := True;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;
    
如果可以使用
CreateProcess
代替
ShellExecute
,则可以等待处理句柄。当应用程序退出时,将发出处理句柄的信号。例如:
function ExecAndWait(APath: string; var VProcessResult: cardinal): boolean;
var
  LWaitResult : integer;
  LStartupInfo: TStartupInfo;
  LProcessInfo: TProcessInformation;
begin
  Result := False;

  FillChar(LStartupInfo, SizeOf(TStartupInfo), 0);

  with LStartupInfo do
  begin
    cb := SizeOf(TStartupInfo);

    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    wShowWindow := SW_SHOWDEFAULT;
  end;

  if CreateProcess(nil, PChar(APath), nil, nil, 
                   False, NORMAL_PRIORITY_CLASS,
                   nil, nil, LStartupInfo, LProcessInfo) then
  begin

    repeat
      LWaitResult := WaitForSingleObject(LProcessInfo.hProcess, 500);
      // do something, like update a GUI or call Application.ProcessMessages
    until LWaitResult <> WAIT_TIMEOUT;
    result := LWaitResult = WAIT_OBJECT_0;
    GetExitCodeProcess(LProcessInfo.hProcess, VProcessResult);
    CloseHandle(LProcessInfo.hProcess);
    CloseHandle(LProcessInfo.hThread);
  end;
end;
ExecAndWait返回后,您可以根据需要睡眠100毫秒。 N @     

要回复问题请先登录注册