Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   ShellExecute Problemchen (https://www.delphipraxis.net/212746-shellexecute-problemchen.html)

TurboMagic 25. Mär 2023 11:39

ShellExecute Problemchen
 
Hallo,

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

Delphi-Quellcode:
function TMyClass.RunInstaller(const FileName, FTempPath: string): Boolean;
var
  ErrorCode : UInt32;
  Param    : string;
begin
  Param := '';

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

  ErrorCode := GetLastError;

  if (ErrorCode <= 32) then
  begin
    WriteLogMsg('Fehler beim Ausführen des Installers:' +
                FileName + ' Code: ' + ErrorCode.ToString + ' Msg.: ' +
                System.SysUtils.SysErrorMessage(ErrorCode, 0));

    Result := false;
  end
  else
    Result := true;
end;
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".

Ja wie nun? Warum sagt dann Microsoft hier:
https://learn.microsoft.com/en-us/wi...-shellexecutea
dass Rückgabewerte <= 32 Fehlercodes sind und 0 wäre "The operating system is out of memory or resources.",
was ja wohl definitiv nicht stimmen kann, denn der Installer startet ja.

Was mache ich falsch?

Grüße
TurboMagic

DeddyH 25. Mär 2023 12:35

AW: ShellExecute Problemchen
 
Wozu GetLastError, wenn ShellExecute selbst bereits einen numerischen Code zurückgibt?

TurboMagic 25. Mär 2023 12:37

AW: ShellExecute Problemchen
 
Zitat:

Zitat von DeddyH (Beitrag 1520316)
Wozu GetLastError, wenn ShellExecute selbst bereits einen numerischen Code zurückgibt?

Ups! Muss ich übersehen haben....
Das wird's sein! Teste ich später...

peterbelow 25. Mär 2023 14:53

AW: ShellExecute Problemchen
 
Zitat:

Zitat von TurboMagic (Beitrag 1520313)
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 }

TurboMagic 25. Mär 2023 15:05

AW: ShellExecute Problemchen
 
Danke für dne Hinweis mit dem nicht warten. Nur: ich will ja gar nicht warten ;-)
Ich kann ja schlecht ein Update Programm starten und auf dessen beendigung warten,
wenn es das Programm, welches gerade läuft, aktualisieren soll ;-)

Das mit dem Rückgabewert ist schon passend. Es scheint zu funktionieren.

uligerhardt 25. Mär 2023 16:39

AW: ShellExecute Problemchen
 
Nimm lieber ShellExecuteEx. Das liefert vernünftige Fehlercodes zurück.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz