Announcement

Collapse
No announcement yet.

Prüfen wann ein gestartetes externes Programm beendet wurde

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Prüfen wann ein gestartetes externes Programm beendet wurde

    Hallöchen,

    Bei mir stellt sich folgendes Problem: Innerhalb einer Funktion rufe ich ein externes Programm mittels ShellExecute auf. Der nachfolgende Befehl der Funktion darf erst abgearbeitet werden, wenn das zuvor gestartete Programm beendet wurde. Das extern gestartete Programm schreibt beim Beenden einen Wert in eine Datei, den ich in der aufrufenden Funktion auslesen möchte. Dies kann ich ja nur wenn das Programm beendet wurde. Bei einer sequentiellen Schreibweise der Befehle innerhalb der Funktion wird mittels ShellExecute das Programm gestartet und anschließend sofort versucht den oben erwähnten Wert auszulesen, obwohl das Programm nach nicht beendet wurde.

    Ich bin für jeden Tip dankbar

    Ciao Ringo

  • #2
    Hallo,

    das folgende Beispiel stammt aus meinem Buch <b>Delphi Win32-Lösungen</b> und demonstriert, wie das eigene Programm den Windows-Taschenrechner startet und auf dessen Programmende wartet:
    <pre>
    procedure TFormMain.Button1Click(Sender: TObject);
    begin
    WaitExecute('calc.exe');
    end;

    {
    Das Programm startet eine andere Win32-Anwendung und wartet auf deren
    Ende. Allerdings soll die eigene Anwendung während dieser Zeit immer
    noch auf Benutzeraktionen und Windows-Botschaften reagieren. Der
    Benutzer kann das Fenster verschieben, als Icon ablegen und wieder
    von der Taskleiste herstellen. Dazu ist es notwendig, das die Win32-
    API-Funktion MsgWaitForMultipleObjects nicht nur beim Ende des gestarteten
    Prozesses zurückkehrt, sondern immer dann, wenn eine neue Botschaft von
    Windows zugestellt wurde. Aus diesem Grund verwendet die API-Funktion
    MsgWaitForMultipleObjects die Konstante QS_ALLINPUT, somit kehrt die
    Funktion bei jeder neuen Botschaft zurück. Über den anschliessenden
    Aufruf von ProcessMessages werden die neuen Botschaften als bearbeitet
    markiert, so dass sich MsgWaitForMultipleObjects wieder für neue
    Botschaften auf Lauer legt, solange der gestartet Prozess noch läuft.
    }

    procedure TFormMain.WaitExecute(sEXE: String);
    var
    aTSI : TStartupInfo;
    aTPI : TProcessInformation;
    iRet : Integer;
    begin
    FillChar(aTSI, SizeOf(aTSI), #0);
    FillChar(aTPI, SizeOf(aTPI), #0);
    aTSI.CB := SizeOf(aTSI);
    if not CreateProcess(nil, PChar(sEXE), nil, nil, False,
    NORMAL_PRIORITY_CLASS,
    nil, nil, aTSI, aTPI) then
    RaiseLastWin32Error;
    StatusBar1.SimpleText := 'Externer Prozess ist aktiv.';
    repeat
    iRet := MsgWaitForMultipleObjects(1, aTPI.hProcess, False, INFINITE,
    (QS_ALLINPUT));
    if iRet <> (WAIT_OBJECT_0) then
    begin
    // aktustische Rückmeldung zur Demonstration
    MessageBeep($FFFFFFFF);
    Application.ProcessMessages;
    end;
    until iRet = (WAIT_OBJECT_0);
    CloseHandle(aTPI.hProcess);
    StatusBar1.SimpleText := 'Externer Prozess wurde beendet.';
    end;
    </pre&gt

    Comment


    • #3
      Besten Dank für die detaillierte Antwort. Diese Funktion entspricht genau meinen Anforderungen.

      Ich glaube, dass ich mir Ihr Buch mal näher anschauen werde

      Comment

      Working...
      X