2009-11-19 3 views
11

Wenn ich meine Code-Dateien als .pyw speichern, erscheint kein Konsolenfenster - was ich will - aber wenn der Code einen Anruf an os.system enthält, bekomme ich immer noch ein lästiges Konsolenfenster. Ich nehme an, es ist durch den Anruf an os.system verursacht. Gibt es eine Möglichkeit, andere Dateien innerhalb meines .pyw-Skripts auszuführen, ohne das Konsolenfenster überhaupt anzuheben?Wie vermeidet man Konsolenfenster mit .pyw-Datei, die os.system-Aufruf enthält?

+0

Related: [Ausführen eines Prozesses in Pythonw mit Popen ohne eine Konsole] (http://StackOverflow.com/q/1813872/95735) –

+0

Ich glaube os.system() öffnet einen neuen Cmd-Prozess. Probieren Sie os.execl() aus, um den neuen cmd-Prozess mit Ihrem pythonw.exe-Prozess zu ERSETZEN. – DevPlayer

Antwort

5

Sie könnten versuchen, die subprocess Modul (subprocess.Popen, subprocess.call oder was auch immer) mit dem Argument shell=True, wenn Sie eine Konsole Startfenster vermeiden wollen.

+1

subprocess.check_call ist in diesem Fall ein guter Ersatz für os.system. – esm

+0

Das hat funktioniert ... Danke! – twneale

+1

Achten Sie darauf, 'subprocess.check_call (args, shell = True)' zu setzen, wobei 'args' die Befehlszeichenfolge ist, die Sie normalerweise in einer Konsole eingeben würden. Ich bin mir nicht sicher, warum 'shell = True' benötigt wird, wenn ich nicht möchte, dass eine Konsole erscheint, aber das ist in meinem Experiment passiert. – Kit

13

Sie sollten subprocess.Popen Klasse Gang als startupinfo Parameterwert Instanz subprocess.STARTUPINFO Klasse verwenden, mit dwFlags Attribut subprocess.STARTF_USESHOWWINDOW Flag und wShowWindow Attribut hält subprocess.SW_HIDE Flag. Dies kann aus den Zeilen 866-868 des subprocess.py Quellcodes abgeleitet werden. Es kann notwendig sein, auch subprocess.CREATE_NEW_CONSOLE Flag als einen Wert von creationflags Parameter übergeben, wie Sie unter pythonw.exe ausführen, die eine Konsole nicht öffnet.

Wenn Sie shell=True verwenden passiert es einfach, dass alle oben genannten richtig eingestellt sind, aber das bedeutet nicht, dass es eine richtige Lösung ist. Ich würde argumentieren, dass dies nicht der Fall ist, weil es zusätzlichen Aufwand für das Ausführen von Befehlsinterpreter und das Analysieren von Argumenten verursacht. Außerdem sollten Sie bedenken, dass (...) die Verwendung von shell = True dringend davon abzuraten ist in Fällen, in denen die Befehlszeichenfolge aus der externen Eingabe gemäß Dokumentation des Subprozessmoduls aufgebaut wird.

+0

Die Eingabe stammt nicht von einer externen Quelle, und ich kann mich nicht um den Overhead kümmern, wenn ich den Shell-Befehl analysiere, vor allem, wenn es um die zu komplizierte Lösung geht, die Sie oben beschreiben. – twneale

+1

Die Verwendung von 'shell = True' ist hier nicht richtig und die (angebliche) Komplexität der richtigen Lösung ändert dies nicht. –

+2

Ich kann nicht glauben, dass dies nicht die höchste Wahl ist. Alles nur, weil die Leute nicht daran interessiert sind, 3 Zeilen Code zu schreiben, um die Dinge richtig zu machen. +1 – hammus

13

Die Lösung, die Piotr beschreibt, ist eigentlich nicht so kompliziert, wie es klingen mag. Hier ist ein Beispiel, wo ein startupinfo zu einem check_call Aufruf übergeben wird das Konsolenfenster zu unterdrücken:

startupinfo = subprocess.STARTUPINFO() 
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW 

subprocess.check_call(cmd, startupinfo=startupinfo) 

Da die Komfortfunktionen call, check_call und check_output vorwärts ihr **kwargs zum Popen Konstruktor, ist es nicht zu verwenden, erforderlich Popen direkt.

+0

-1: Fehler auf dem Mac. – ArtOfWarfare

+2

@ArtOfWarfare Diese Frage ist spezifisch für Windows, daher ist es nicht verwunderlich, dass es auf anderen Betriebssystemen fehlschlagen kann. Wenn Sie helfen möchten, sollten Sie den genauen Fehler angeben, den Sie unter Mac OS erhalten. –

+0

Es ist eine aufwendige Arbeit um (relativ zu wie viel Code sonst notwendig ist), so dass ein System (Windows) sich wie die anderen verhalten kann, aber dabei die anderen bricht. Ich gehe mit 'shell = true' - es ist kurz, es ist süß, und es funktioniert auf allen Plattformen.Oh, und das Problem auf Mac (und ich nehme an * nix) ist, dass es eine Ausnahme über 'STARTUPINFO()' gibt, die nicht erkannt wird. – ArtOfWarfare

1

Es scheint, dass 'os.popen' kein Konsolenfenster erzeugt. Skript läuft unter 'pythonw'. Nicht sicher über alle Fälle, aber in meinem Fall funktioniert es gut.

os.popen(command) 
7

Menschen sind ein bisschen faul ... ich @Piotr Dobrogost und @Frank S. Thomas für ihre Antworten thx würde.

kam ich diesen Code mit dem auf Linux und Windows ist runinng:

import platform 
import subprocess 
startupinfo = None 
if platform.system() == 'Windows': 
    import _subprocess # @bug with python 2.7 ? 
    startupinfo = subprocess.STARTUPINFO() 
    startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW 
    startupinfo.wShowWindow = _subprocess.SW_HIDE 

später ...

args = [exe, ...] 
out = subprocess.check_output(args, startupinfo=startupinfo) 

Thx Jungs;)

Zusätzlich: nur zu beachten, dass die Der folgende Code mit 'call' funktioniert auch auf Python 2.7 (unter Windows) mit dem ‚STARTUP‘ Code oben:

def run_command(cmd, sin, sout): 
    print "Running cmd : %s"%(" ".join(cmd)) 
    return subprocess.call(cmd, stdin=sin, stdout=sout, startupinfo=startupinfo) 
+0

Das funktionierte perfekt für mich, danke. Ich kann nicht verstehen, warum irgendjemand Shell = True verwenden möchte, es ist nur ein Fehler, der darauf wartet, passiert zu sein. – Whatang

0

Ähnlich wie @firsthand sagte ich in den Foren wxPython-Benutzer gelesen haben, dass Sie die aktuelle laufende Anwendung „ersetzen“, dass sein „command.com“ oder „cmd.exe“, würde mit pyw.exe oder pythonw.exe, wenn Sie so etwas wie die folgenden verwenden:

os.execl(sys.executable, *([sys.executable]+sys.argv)) 

another post

sehen Obwohl ich weiß nicht, wie Sie würde in diesem Fall io pipen.

Ich glaube, ein Vorteil dieses Ansatzes ist, wenn Sie Ihr Skript mehrmals Ihre OS-Taskleiste mit nicht füllen mit CMD-Icons ausführen. Andersherum, wenn Sie mehrere CMD in der Taskleiste minimiert haben und anfangen, sie zu schließen, ist es unmöglich zu sagen, welches CMD mit welchem ​​Pythonw-Skript geht.

Verwandte Themen