QProcess und Eingabeaufforderung

Alles rund um die Programmierung mit Qt
Antworten
TK
Beiträge: 74
Registriert: 3. April 2009 11:33

QProcess und Eingabeaufforderung

Beitrag von TK »

Hallo zusammen,

ich möchte gerne ein externes Programm, bla.exe, über die Eingabeaufforderung starten.

Mittels

Code: Alles auswählen

QProcess Process;
Process.startDetached("C:/Windows/system32/cmd.exe");
starte ich die Eingabeaufforerung.
Doch jetzt muss ich den Pfad von bla.exe eingeben (mit diversen Argumenten). Wie kann ich nun in die Eingabeaufforderung "schreiben"?
Etwa mit write("cd C:\\n")?

Danke für eure Hilfe.
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

z.B. mit

Code: Alles auswählen

cmd.exe /k dir
siehe:
cmd.exe /?
Linux, das längste Text-Adventure aller Zeiten
TK
Beiträge: 74
Registriert: 3. April 2009 11:33

Beitrag von TK »

Hallo RavenIV,

danke für den Tipp. Läuft.

Läuft, bis zum nächsten/letzten Punkt und zwar soll der Process nun natürlich korrekt beendet werden.

Dachte da an:

Code: Alles auswählen

        if (true != process.waitForFinished())
        {
                    QMessageBox::critical(this, tr("myApp"),
                                                            tr("FEHLER"),
                                                            QMessageBox::Ok);
        }
        else
        {
                    QMessageBox::information(this, tr("myApp"),
                                                                   tr("ALLES SUPER"),
                                                                   QMessageBox::Ok);
        }
Aufgerufen wird immer der if-Zweig, warum? Auch, wenn ich waitForFinished ein timeout übergebe. Was ist daran falsch?
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

Wenn die Eingabeaufforderung nach vollendeter Arbeit nicht mehr benötigt wird (und das Ergebnis nicht angeschaut werden muss) kannst du

Code: Alles auswählen

cmd.exe /c
verwenden.
Linux, das längste Text-Adventure aller Zeiten
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

waitForFinished() beendet das Programm auch nicht - der Name sagt es ja schon, es wartet nur. Wenn du dem Prozess nicht sagst "geh tot!", kann waitForFinished() auch warten was es will.
Setze vorher ein process.terminate() ab, dann sollte das waitForFinished auch mit true beenden.
Deine if-Abfrage ist im übrigen etwas sehr unorthodox. Normalerweise schreibt man

Code: Alles auswählen

if (!process.waitForFinished())
Deine Schreibweise benötigt mehrere Schritte zur Erfassung. "true" "!=" "method()" kombinieren und auswerten. "false" "==" "method()" ist schon angenehmer, die Kurzform oben allerdings am schnellsten erfassbar. Ist jetzt nicht wg. Laufzeit, sondern nur wg. Lesen des Codes.
TK
Beiträge: 74
Registriert: 3. April 2009 11:33

Beitrag von TK »

Hallo franzf,

danke für deine Erklärung. Werde es umsetzen und feedback geben. :D
Ist jetzt nicht wg. Laufzeit, sondern nur wg. Lesen des Codes.
Darüber gibt es unzählige unterschiedliche Meinungen.
Ich kenne und lebe die coding guidelines, welche die Variante "false" "==" "method()" empfehlen.
TK
Beiträge: 74
Registriert: 3. April 2009 11:33

Beitrag von TK »

Also mit process.terminate() kann ich die Eingabeaufforderung nicht beenden.
Habe folgendes gelesen:
QProcess::terminate() schickt eine WM_CLOSE-Nachricht an das Programm.
Dieses muss natürlich darauf reagieren.

Ich bin mir nicht sicher, ob die Eingabeaufforderung darauf reagieren kann.

Wenn ich aber das Kommando, welches ich über die Eingabeaufforerung absetze, über"cmd.exe /C cd ... "; ausführe, bewirkt ja das C folgendes:
/C Führt den Befehl in der Zeichenfolge aus und endet dann.
Ist es damit schon getan oder ist mein Process doch noch am Leben?

Schönen Abend noch.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

TK hat geschrieben:Habe folgendes gelesen:
QProcess::terminate() schickt eine WM_CLOSE-Nachricht an das Programm.
Dieses muss natürlich darauf reagieren.
Laut Doku korrekt, nach dem Satz hast du leider das Lesen aufgehört, danach kommt nämlich noch:
Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill().

Code: Alles auswählen

process.kill();
und gut ists. Ist natürlich doof, wenn das mit nem kill getötet werden muss. Ein terminate ist normalerweeise die höflichere Art, da hier eben noch Arbeit erledigt werden kann. Das kill "tötet" den Prozess.
Wenn das tatsächlich stimmt, dass cmd.exe sich nicht ums WM_CLOSE schert und sich deshalb nicht geregelt terminieren lässt - jippie ^^
Wunder mich nur, wie das dann mit dem "X" in der Fensterleiste klappt. Sendet das dann etwas spezielleres? Hätte vermutet, dass das auch ein einfaches "WM_CLOSE" ist.
TK
Beiträge: 74
Registriert: 3. April 2009 11:33

Beitrag von TK »

Also die Codezeile

Code: Alles auswählen

process.startDetached("C:\\Windows\\system32\\cmd.exe", cmd);
öffnet die Eingabeaufforderung und führt das Kommando "cmd" aus.

Die Codezeile anschließend danach

Code: Alles auswählen

process.kill();
bewirkt irgendwie gar nichts. Die Eingabeaufforderung bleibt weiterhin im Fenster geöffnet.

Kann ich die Eingabeaufforderung also NUR über "cmd.exe /C cd ... "; direkt nach der Abbarbeitung des Kommandos wieder schließen? Mit kill wohl nicht, oder ist das irgendwo noch ein BUG.
Antworten