Announcement

Collapse
No announcement yet.

Ausführen von Anwendungen

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

  • Ausführen von Anwendungen

    hallo !

    ich suche eine api funktion zum ausführen von exe-dateien, die lokal auf der platte liegen. shellexecute ist bekannt, jedoch suche ich eine funktion, die auf das schließen dieser anwendung wartet und mir den errorlevel zurückgibt (à la bp7).

    thx

  • #2
    Hallo,

    das folgende Beispiel startet einen Prozess und wartet auf das Ende. Um den ErrorLevel auszuwerten, muss vor dem Schliessen des Prozess-Handles die Win32-API-Funktion <b>GetExitCodeProcess</b> zusätzlich aufgerufen werden:
    <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>
    P.S: Das Beispiel stammt aus meinem neuen (demnächst erscheinenden) Buch <b>Delphi Win32-Lösungen</b>

    Comment


    • #3
      die 'waitexecute' von ihnen habe ich im forum schon gesehen. mir fehlte nur noch die info über 'GetExitCodeProcess'.

      danke

      Comment


      • #4
        ok - funktioniert wunderbar !

        für alle, die diese funktion ebenfalls brauchen, hier die angepaßte 'waitexecute' mit errorlevel als rückgabewert.

        <pre>
        function TFormMain.WaitExecute(sEXE: string): Cardinal;
        var
        aTSI : TStartupInfo;
        aTPI : TProcessInformation;
        iRet : Integer;
        ExitCode: Cardinal;
        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;
        repeat
        iRet := MsgWaitForMultipleObjects(1, aTPI.hProcess, False, INFINITE,
        (QS_ALLINPUT));
        if iRet <> (WAIT_OBJECT_0) then
        Application.ProcessMessages;
        until iRet = (WAIT_OBJECT_0);
        ExitCode:= 0;
        if not GetExitCodeProcess(aTPI.hProcess, ExitCode) then
        RaiseLastWin32Error;
        Result:= ExitCode;
        CloseHandle(aTPI.hProcess);
        end;
        </pre&gt

        Comment


        • #5
          An Andreas Kosch: Ich benutze Ihre Funktion in einem Projekt das unter GNU-License läuft. Ich möchte in den Credits Ihren Namen nennen. Sollte Ihr Buch rauskommen, könnte ich auch einen Link auf z.B. eine amazon.de-Seite richten, bei der man Ihr Buch bestellen kann.<p>
          Ich bräuchte nur Ihr Einverständniss per eMail: [email protected]<p>
          Danke!<p>
          Patrik Hübne

          Comment


          • #6
            Hallo Patrik,

            das wäre mit Kanonen auf Spatzen geschossen;-) <br>
            Eine Werbung für mein Buch kann aber nie schaden, als Link dazu ist <b>http://entwickler.com/buch/</b> universell nutzbar (dort sind alle meine aktuellen Bücher erreichbar)

            Comment


            • #7
              hmm..der Link funktioniert nicht..

              Comment


              • #8
                Hallo,

                in diesem Fall würde ich den Link <b>Bücher</b> am linken Rand dieser Webseite verwenden (zumal es dort egal ist, wenn die Struktur der Webseite intern verändert wird)

                Comment

                Working...
                X