Seite 1 von 2
Subprocess öffnet Konsolenfenster
Verfasst: Dienstag 12. April 2011, 12:31
von twessels
Hallo,
ich starte mit subprocess.popen(...) einen neuen Prozess und lese dann dessen Ausgabe. Klappt auch wunderbar, nur öffnet sich bei einem Kollegen jedesmal ein Konsolenfesnter(cmd.exe), welches sich auch gleich wieder schließt (Prozess zu Ende). Bei mir zeigt sich dieses Verhalten nicht, obwohl ich ebenfalls WindowsXP-SP2 am Laufen habe. Python-Version ist dieselbe.
Ist ein bisschen nervig, da ich mit xcopy mehrere Dateien kopiere und entsprechend oft ein neuer Prozess gestartet wird.
Wie kann ich das "aufpoppen" der Konsole verhindern?
Hier der Code:
Code: Alles auswählen
def runProcess(self, cmd, name):
try:
exec_dir = os.getcwd()
if verboseFlg:
if gui == True:
# self.printer("opening process %s" % " ".join(cmd), self.tabNum, myout['std'])
p = Popen(cmd, bufsize=1, cwd=exec_dir, stderr=subprocess.STDOUT, stdout=PIPE) #redirect stderr to stdout and stdout to pipe
# self.printer("process opened", self.tabNum, myout['std'])
#reading from pipe
with p.stdout as f:
# self.printer("reading to buffer", self.tabNum, myout['info'])
read_data = f.read() # read() blocks until buffer is full or subprocess returns
self.printer(read_data, self.tabNum, myout['ext'])
f.closed
# self.printer("process closed", self.tabNum, myout['std'])
else:
subprocess.check_call(cmd, bufsize=1, cwd=exec_dir)
else:
fnull = open(os.devnull, "w")
subprocess.check_call(cmd, bufsize=1, cwd=exec_dir, stderr=fnull, stdout=fnull)
fnull.close()
except subprocess.CalledProcessError,e:
self.printer("%s failed" % name, self.tabNum, myout['err'])
else:
# self.printer("%s finished" % name, self.tabNum, myout['std'])
pass
Re: Subprocess öffnet Konsolenfenster
Verfasst: Dienstag 12. April 2011, 17:13
von Dauerbaustelle
Nutzt der Kollege denn das exakt gleiche Python-Script?
Re: Subprocess öffnet Konsolenfenster
Verfasst: Mittwoch 13. April 2011, 00:30
von Leonidas
Und fairerweise muss man sich auch fragen warum du ``xcopy`` verwendest, wenn Python doch auch Dateien kopieren kann.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Donnerstag 14. April 2011, 20:57
von twessels
Ja, er nutzt exakt das gleiche Script!
Ja, Python kann zwar auch Dateien kopieren ist aber ziemlich aufwendig wenn man ganze Ordner mit Inhalt in andere Ordner kopieren will (Zielverzeichnis muss laut shutil leer sein, Ordner werden nicht automatisch erstellt). Ich will dies aber nicht zum Topic machen, da die runProcess(..) Methode noch weitere Programme ausführt und immer ein Konsolenfenster aufpoppt.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 07:58
von Xynon1
Startet ihr das Script auch gleich, oder nutzt du es aus einem Terminal und er per Doppelklick ? Denn bei Doppelklick sollte bei der Art eigentlich immer die Shell-Konsole aufgehen.
Wenn nicht, könntest du mal die Parameter im Aufruf posten?
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 08:52
von twessels
@Xynon1
Aha, darin lag der Unterschied! Er hat das Script (grafische PyQt4-Anwendung) durch Doppelklicken gestartet, ich über die Konsole. Bei mir zeigt sich jetzt auch das Verhalten.
Wie sieht da die Lösung aus? -Ein Batch-Script schreiben und darin Python aufrufen?
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 09:05
von Xynon1
Hehe, darüber hatte ich beim schreiben auch schon nachgedacht, nur fällt mir dazu nichts ein. Theoretisch sollte das in einem Batchscript durch den Befehl "start /B" unterbunden werden, das die Konsole geöffnet bleibt.
Ich versteh aber auch nicht wieso man das Kopieren nicht direkt mit Python gehen sollte. Das wäre wesentlich sauberer.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 12:07
von twessels
Die Konsole bleibt zum Glück nicht geöffnet, sondern schließt sich nach dem Prozess-Ende. Bei kurzen Prozessen sieht man quasi nur ein schwarzes Fenster aufblinken.
Start /B kannte ich noch garnicht
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 12:43
von Xynon1
Mit xcopy wirst du warscheinlich auch nichts besseres hinbekommen, denn das ist auch nur eine Win32-Konsolen Programm. AFAIK konnte man die Konsole nur mit der Windows-API aus "user32.dll" mit der Funktion "ShowWindow" ausblenden oder musste eine FreeConsole nutzen. Beides ist aber bei xcopy nicht der Fall und da xcopy schon ein Kompilat ist, wirst du das auch nicht ändern können. Somit wird diese immer "aufpoppen", eventuell kannst du noch /MIN an start ranhängen, dann wird sie minimiert.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 13:00
von twessels
Ok, ich rufe mit dem Programm aber auch einen proprietären Compiler, ein Komprimierungstool für Images und einen EEPROM-Flasher auf. Also bringt es nicht viel wenn ich xcopy in native Python-Code nachprogrammiere und die anderen Tools nicht.
Wenn ich das Programm aus einem Batch-Script heraus aufrufe funktioniert es soweit super. Es öffnet sich nur ein einziges Konsolenfenster. Damit kann ich erstmal Leben.
Werde mir die Subprocess-Klasse aber nochmal genau anschauen...
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 13:04
von BlackJack
@twessels: Grundsätzlich ist das Konsolenfenster eine Entscheidung von Windows wenn es ein Programm startet. Es wird zwischen Konsolen-Programmen und Windows-Programmen unterschieden. Diese Information holt sich Windows aus der jeweiligen `*.exe`. Irgendwie kann man mit dem `creationflags`-Argument aber wohl unter Windows auch bei Konsolen-Programmen verhindern dass da ein Konsolenfenster erstellt wird. Damit wird der Code an der Stelle dann plattformabhängig.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 13:13
von Xynon1
@BlackJack
Hatte ich oben schon zwei Methoden genannt wie man das in Windows machen könnte. Theoretisch könnte man auch einen Dienst statt einen Konsolen-Programm schreiben. Aber für die Methoden bräuchte man immer den Sourcecode.
Irgendwo gab es auch noch ein Zusatztool namens HideConsole, oder so ähnlich, welches von außen die Konsole verbirgt.
Edit:
http://beta.unclassified.de/projekte/hideconsole/
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 13:21
von snafu
Der Quelltext besteht aus wenigen Zeilen. Das dürfte also auch mittels ``ctypes`` umsetzbar sein.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 13:28
von Gremlin
BlackJack hat geschrieben:Irgendwie kann man mit dem `creationflags`-Argument aber wohl unter Windows auch bei Konsolen-Programmen verhindern dass da ein Konsolenfenster erstellt wird.
Ich bin mal (wieder) so frei:
Code: Alles auswählen
p = Popen(cmd, bufsize=1, cwd=exec_dir, stderr=subprocess.STDOUT, stdout=PIPE, creationflags=0x08000000)
BlackJack hat geschrieben:Damit wird der Code an der Stelle dann plattformabhängig.
Das ist er doch sowieso schon? (xcopy)
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 14:54
von twessels
Hallo, so funktioniert es. Ganz ohne Batch-Script.
Man beachte
Code: Alles auswählen
def runProcess(self, cmd, name):
try:
exec_dir = os.getcwd()
if verboseFlg:
if gui == True:
# self.printer("opening process %s" % " ".join(cmd), self.tabNum, myout['std'])
# do not show window
info = subprocess.STARTUPINFO()
info.dwFlags = _subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = _subprocess.SW_HIDE
# open process and redirect stderr to stdout and stdout to pipe
p = Popen(cmd, bufsize=1, cwd=exec_dir, stderr=subprocess.STDOUT, stdout=PIPE, startupinfo=info)
# self.printer("process opened", self.tabNum, myout['std'])
#reading from pipe
with p.stdout as f:
# self.printer("reading to buffer", self.tabNum, myout['info'])
read_data = f.read() # read() blocks until buffer is full or subprocess returns
self.printer(read_data, self.tabNum, myout['ext'])
f.closed
# self.printer("process closed", self.tabNum, myout['std'])
else:
subprocess.check_call(cmd, bufsize=1, cwd=exec_dir)
else:
fnull = open(os.devnull, "w")
subprocess.check_call(cmd, bufsize=1, cwd=exec_dir, stderr=fnull, stdout=fnull)
fnull.close()
except subprocess.CalledProcessError,e:
self.printer("%s failed" % name, self.tabNum, myout['err'])
else:
# self.printer("%s finished" % name, self.tabNum, myout['std'])
pass
meine xcopy Funktion ist übrigens wohl plattformunabhängig:
Code: Alles auswählen
def xcopy_(self, src, dst, recursive=True):
if os.name == 'nt':
# Y=Unterdrückung Bestätigungsaufforderung, E=Rekursiv, I=Annahme, dass Ziel ein Verzeichnis ist, C=Continue bei Fehler
cmd = ['xcopy', '/Y', '/E', '/C', src, dst] if recursive==True else ['xcopy', '/Y', src, dst]
self.printer(" ".join(cmd), self.tabNum, myout['std'])
self.runProcess(['cmd.exe', '/C', 'echo d', '|'] + cmd, " ".join(cmd))
elif os.name == 'posix':
cmd = ['cp', '-R', src, dst] if recursive==True else ['cp', src, dst]
self.runProcess(['cmd.exe', '/C', 'echo d', '|'] + cmd, " ".join(cmd))
else:
try:
self.printer("copytree %s %s" % (src, dst), self.tabNum, myout['std'])
shutil.copytree(src, dst, ignore='.svn') if recursive==True else shutil.copy2(src, dst)
except (IOError, OSError), why:
print str(why)
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 15:21
von BlackJack
@twessels: Hm, bei Python 2.6, 2.7, und 3.1 bekomme ich ``ImportError: No module named _subprocess``.

Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 15:44
von snafu
Zudem gibt es (getestet in 2.6) auch kein Attribut namens ``STARTUPINFO``.
EDIT: Der betreffende Code bestand mal, wurde dann aber
rausgenommen. Und ``STARTUPINFO`` besteht nur unter Windows, ist aber (wie im Link erwähnt) nicht dokumentiert, sodass sich auch nicht drauf verlassen werden sollte.
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 16:07
von Xynon1
twessels hat geschrieben:Code: Alles auswählen
elif os.name == 'posix':
cmd = ['cp', '-R', src, dst] if recursive==True else ['cp', src, dst]
self.runProcess(['cmd.exe', '/C', 'echo d', '|'] + cmd, " ".join(cmd))
Sag mal wie wird cmd.exe bei dir unter unixoiden Systemen ausgeführt ?
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 16:09
von twessels
Ich hab
Python 2.7 am Laufen.
Hier hab ich das Snippet her:
http://stackoverflow.com/questions/4703 ... showwindow
Code: Alles auswählen
import subprocess # to execute external programs
print(subprocess.__file__)
import _subprocess
Wenn ich mit
versuche den Pfad zu erhalten, krieg ich allerdings einen Fehler.
Ich glaube durch das '_' wird Python darüber informiert, dass er eine alte Version der Lib benutzen soll
Re: Subprocess öffnet Konsolenfenster
Verfasst: Freitag 15. April 2011, 16:12
von twessels
Xynon1 hat geschrieben:
Sag mal wie wird cmd.exe bei dir unter unixoiden Systemen ausgeführt ?

, copy&paste fehler. Teste das Tool nicht sehr häufig unter Linux