Home » Tipps & Tricks » System » Prozesse » Verwendung von CreateProcess

Verwendung von CreateProcess

Um ein anderes Programm zu starten sollte man CreateProcess benutzen, da diese Funktion sehr viele Parameter kennt. Hier eine Funktion, die den Umgang damit erleichtert. In AFilename wird der Dateiname des Programms übergeben, in AParameter kann die Parameterzeile angegeben werden, in ACurrentDir übergibt man ein alternatives Startverzeichnis, bei einem leeren String wird das Verzeichnis der Exe benutzt. Setzt man ACurrentDir auf ein nicht vorhandenes Verzeichnis, startet die Anwendung nicht. Wenn AWait True ist, wartet das Programm darauf, dass das aufgerufene Programm beendet wird.Übergibt man den optionalen Parameter AOnWaitProc, so wird diese Funktion etwa alle 50 ms aufgerufen, bis das gestartete Programm wieder geschlossen wird.Über die Parameter, die AOnWaitProc übergeben werden, kann man auf den Prozess zugreifen und ihn ggf. beenden.

type
  TExecuteWaitEvent = procedure(const ProcessInfo: TProcessInformation;
                                    var ATerminate: Boolean) of object;

procedure ExecuteFile(const AFilename: String;
                 AParameter, ACurrentDir: String; AWait: Boolean;
                 AOnWaitProc: TExecuteWaitEvent=nil);
var
  si: TStartupInfo;
  pi: TProcessInformation;
  bTerminate: Boolean;
begin
  bTerminate := False;

  if Length(ACurrentDir) = 0 then
    ACurrentDir := ExtractFilePath(AFilename);

  if AnsiLastChar(ACurrentDir) = '' then
    Delete(ACurrentDir, Length(ACurrentDir), 1);

  FillChar(si, SizeOf(si), 0);
  with si do begin
    cb := SizeOf(si);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := SW_NORMAL;
  end;

  FillChar(pi, SizeOf(pi), 0);
  AParameter := Format('"%s" %s', [AFilename, TrimRight(AParameter)]);

  if CreateProcess(Nil, PChar(AParameter), Nil, Nil, False,
                   CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or
                   NORMAL_PRIORITY_CLASS, Nil, PChar(ACurrentDir), si, pi) then
  try
    if AWait then
      while WaitForSingleObject(pi.hProcess, 50) <> Wait_Object_0 do
      begin
        if Assigned(AOnWaitProc) then
        begin
          AOnWaitProc(pi, bTerminate);
          if bTerminate then
            TerminateProcess(pi.hProcess, Cardinal(-1));
        end;

        Application.ProcessMessages;
      end;
  finally
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
  end;
end;

Beispielaufruf (kein Warten)

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteFile('c:\windows\notepad.exe', '', '', false);
end;

Beispielaufruf (mit Warten)Die Anwendung wird mit Button1 gestartet und kann mit Button2 beendet werden.

type
TForm1 = class(TForm)
  ...
private
  FTerminate: Boolean;
  procedure DoOnExecuteWait(const ProcessInfo: TProcessInformation;
                                   var ATerminate: Boolean);
end;


procedure TForm1.DoOnExecuteWait(const ProcessInfo: TProcessInformation;
                                   var ATerminate: Boolean);
begin
  ATerminate := FTerminate;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FTerminate := False;
  ExecuteFile('C:\Windows\notepad.exe', '', '', True, DoOnExecuteWait);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  FTerminate := True;
end;

Im Gegensatz zu Shellexecute können so wirklich nur ausführbare Programme gestartet werden.Nähere Informationen sind im PSDK unter dem Stichwort Process_Information zu finden.

3 Gedanken zu „Verwendung von CreateProcess“

  1. WaitForSingleObject(pi.hProcess, 50)  Wait_Object_0
    
    Hier fehlt das Gleich/Ungleichheitszeichen - da ich den Code noch nicht vollständig blicke: 
    Könnte es bitte jemand mit Ahnung ergänzen? Danke 🙂
      1. Ja, das kommt leider des Öfteren vor. Die Vergleichszeichen sind vermutlich schon vor längerer Zeit bei einer Umstelloung verloren gegangen.
        Ich freue mich über jede Rückmeldung, dann kann ich Fehler kurzfristig beheben.
        Danke!

Kommentare sind geschlossen.