Wait before ShellExecute is carried out?

后端 未结 3 1048
我在风中等你
我在风中等你 2021-02-15 03:54

I have a hopefully quick question: Is it possible to delay execution of ShellExecute a little bit?

I have an application with autoupdater. After it downloads all necess

3条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-02-15 04:45

    This routine is some utils code in our game engine. It can run an executable and optionally wait for it to exit. It will return its exit code:

    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;
    

    Here is some code that can check to see if a process exists. So... current app calls the updater and terminates. The updater can check to see if old app has terminated and do it's thing (rename, update, delete, etc):

    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;
    

提交回复
热议问题