Einzelnen Beitrag anzeigen

peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
673 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: ShellExecute Problemchen

  Alt 25. Mär 2023, 14:53
Hallo,

gegeben Delphi 11.3 und mein versuch per SHell Execute einen Installer von mir aufzurufen.

Delphi-Quellcode:
  Winapi.ShellAPI.ShellExecute(0, PWideChar('open'), PWideChar(FileName),
    PWideChar(Param), PWideChar(FTempPath), SW_SHOW);

  ErrorCode := GetLastError;
Mein Problem ist jetzt, dass der Installer problemlos gestartet wird, aber ErrorCode
immer 0 ist und die per SysErrorMessage abgeholte Fehlermeldung lautet: "Der Vorgang
wurde erfolgreich beendet".
Was mache ich falsch?
Du hast übersehen, dass ShellExecute nicht wartet, bis der gestartete Prozess beendet ist. Du brauchst sowas wie das hier:

Delphi-Quellcode:
{!
<summary>
Executes a program and waits for it to terminate</summary>
<returns>
-1 in case of error, otherwise the programs exit code</returns>
<param name="FileName">contains executable name + any parameters.
Always use a full pathname, and enclose the name in double quotes
if it contains spaces. Rules are the same as for a command prompt.</param>
<param name="Visibility">
is one of the ShowWindow options, e.g. SW_SHOWNORMAL</param>
<remarks>
In case of error SysErrorMessage(GetlastError) will return an
error message. The routine will process paint messages and messages
send from other threads while it waits.</remarks>
}

function WinExecAndWait32V2(FileName: string; Visibility: integer):
  DWORD;

  procedure WaitFor(processHandle: THandle);
  var
    msg: TMsg;
    ret: DWORD;
  begin
    repeat
      ret := MsgWaitForMultipleObjects(
        1, { 1 handle to wait on }
        processHandle, { the handle }
        False, { wake on any event }
        INFINITE, { wait without timeout }
        QS_PAINT or { wake on paint messages }
        QS_SENDMESSAGE { or messages from other threads }
        );
      if ret = WAIT_FAILED then
        Exit; { can do little here }
      if ret = (WAIT_OBJECT_0 + 1) then begin
          { Woke on a message, process paint messages only. Calling
            PeekMessage gets messages send from other threads processed. }

        while PeekMessage(msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
          DispatchMessage(msg);
        PeekMessage(msg, 0, 0, 0, PM_NOREMOVE); // prevents ghosting
      end;
    until ret = WAIT_OBJECT_0;
  end; { Waitfor }
var { V1 by Pat Ritchey, V2 by P.Below }
  zAppName: array[0..512] of char;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin { WinExecAndWait32V2 }
  StrPCopy(zAppName, FileName);
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
    zAppName, { pointer to command line string }
    nil, { pointer to process security attributes }
    nil, { pointer to thread security attributes }
    false, { handle inheritance flag }
    CREATE_NEW_CONSOLE or { creation flags }
    NORMAL_PRIORITY_CLASS,
    nil, { pointer to new environment block }
    nil, { pointer to current directory name }
    StartupInfo, { pointer to STARTUPINFO }
    ProcessInfo) { pointer to PROCESS_INF }
  then
    Result := DWORD(-1) { failed, GetLastError has error code }
  else begin
    Waitfor(ProcessInfo.hProcess);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end; { Else }
end; { WinExecAndWait32V2 }
Peter Below
  Mit Zitat antworten Zitat