Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Windows API / MS.NET Framework API (https://www.delphipraxis.net/20-library-windows-api-ms-net-framework-api/)
-   -   Delphi Programm starten ohne Shellexecute (https://www.delphipraxis.net/885-programm-starten-ohne-shellexecute.html)

Luckie 19. Sep 2002 20:19


Programm starten ohne Shellexecute
 
Laut PSDK dient Shellexecute nicht dazu eine fremde Anwendung zu starten, sondern
Zitat:

Performs an operation on a specified file
.
Also um zum Beispiel eine Textdatei zu drucken ruft man Shellexecute mit dem Verb 'print' und der entsprechenden Datei auf. Das man damit auch fremde Anwendungen starten kann ist ein Abfallprodukt und ist eher als Mißbrauch zu sehen.

Wenn man es richtig machen will, sollte man CreateProcess benutzen.

Ich habe dazu mal eine kleine Funktion gebastelt. Der Funktion übergibt man den Pfad mit der Anwendung, ein Flag, welcher bestimmt, ob gewartet werden soll oder nicht bis die gestartetet Anwendung beendet ist und eine Variable vom Typ Cardinal, die dann die ProzessID enthält.

[edit=Daniel G]
himitsu hat an dieser Stelle die Funktion um ein paar Fehlerchen bereinigt. Die Änderungen sind hier bereits übernommen.
[/edit]


Delphi-Quellcode:
function RunProcess(FileName: string; ShowCmd: DWORD; wait: Boolean; ProcID: PCardinal): Longword;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb         := SizeOf(StartupInfo);
  StartupInfo.dwFlags    := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  StartupInfo.wShowWindow := ShowCmd;
  if not CreateProcess(nil,
    @Filename[1],
    nil,
    nil,
    False,
    CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS,
    nil,
    nil,
    StartupInfo,
    ProcessInfo)
    then
      Result := WAIT_FAILED
  else
  begin
    try
      if not wait then
      begin
        if ProcID <> nil then ProcID^ := ProcessInfo.dwProcessId;
        Result := S_OK;
        exit;
      end;
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      GetExitCodeProcess(ProcessInfo.hProcess, Result);
    finally
      CloseHandle(ProcessInfo.hProcess);
      CloseHandle(ProcessInfo.hThread);
    end;
  end;
end;
[edit=fkerber]Neu abgespeichert wg. Code-Highlighting. Mfg, fkerber[/edit]

theomega 19. Sep 2002 21:49

was muß man den für Procid einsetzten?

Luckie 19. Sep 2002 21:53

Eine Ganzahl Variable.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  ProcID: Cardinal;
begin
  if OpenDialog1.Execute then
    RunProcess(OpenDialog1.FileName, SW_MINIMIZE, TRUE, ProcID);
  Messagebox(0, 'fertig', @OpenDialog1.Filename[1], 0);
end;
[edit=fkerber]Neu abgespeichert wg. Code-Highlighting. Mfg, fkerber[/edit]

fkerber 31. Aug 2007 18:10

Re: Programm starten ohne Shellexecute
 
sh17 und winkel79 stellen in diesem Thread eine Funktion vor, die es auch ermöglicht ein Programm unter Vista (mit aktivierter UAC) zu starten, ohne dass es zu Fehlermeldungen kommt, weil Rechte fehlen:

Delphi-Quellcode:
function ExecAndWait(Filename, Params: Widestring; WindowState: word = SW_SHOWNORMAL): boolean;
var
  ShExecInfoW: SHELLEXECUTEINFOW;
  ShExecInfoA: SHELLEXECUTEINFOA;
  r : Cardinal;
begin
  Result := false;
  if Filename = '' then exit;
  if not WideFileExists(FileName) then
    exit;

  if Win32IsUnicode then
  begin
    ZeroMemory(@ShExecInfoW, SizeOf(ShExecInfoW));
    ShExecInfoW.Wnd := GetForegroundWindow;
    ShExecInfoW.cbSize := sizeof(SHELLEXECUTEINFOW);
    ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS;
    ShExecInfoW.lpVerb := 'open';
    ShExecInfoW.lpFile := PWideChar(Filename);
    ShExecInfoW.lpParameters := PWideChar(Params);
    ShExecInfoW.lpDirectory := PWideChar(WideExtractFileDir(Filename));
    ShExecInfoW.nShow := WindowState;
    Result := ShellExecuteExW(@ShExecInfoW);
  end
  else
  begin
    ZeroMemory(@ShExecInfoA, SizeOf(ShExecInfoA));
    ShExecInfoA.Wnd := GetForegroundWindow;
    ShExecInfoA.cbSize := sizeof(SHELLEXECUTEINFOA);
    ShExecInfoA.fMask := SEE_MASK_NOCLOSEPROCESS;
    ShExecInfoA.lpVerb := 'open';
    ShExecInfoA.lpFile := PChar(AnsiString(Filename));
    ShExecInfoA.lpParameters := PChar(AnsiString(Params));
    ShExecInfoA.lpDirectory := PChar(AnsiString(WideExtractFileDir(Filename)));
    ShExecInfoA.nShow := WindowState;
    Result := ShellExecuteExA(@ShExecInfoA);
  end;
  try
    if Result then
    begin
      if Win32IsUnicode then
        r := WaitForSingleObject(ShExecInfoW.hProcess, INFINITE)
      else
        r := WaitForSingleObject(ShExecInfoA.hProcess, INFINITE);
    end;
  finally
    if Win32IsUnicode then
      CloseHandle(ShExecInfoW.hProcess)
    else
      CloseHandle(ShExecInfoA.hProcess);
  end;
end;
Win32IsUnicode steht dabei für ein globales
Delphi-Quellcode:
(Win32Platform = VER_PLATFORM_WIN32_NT)
Weitere Infos gibt es hier:
http://msdn.microsoft.com/library/de...lexecuteex.asp
http://msdn.microsoft.com/library/de...xecuteinfo.asp


Alle Zeitangaben in WEZ +2. Es ist jetzt 22:58 Uhr.

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