2009-11-19 20 views
11

Se salvi i miei file di codice come .pyw, non viene visualizzata alcuna finestra della console, che è ciò che voglio, ma se il codice include una chiamata a os.system, ho ancora una fastidiosa finestra della console. Presumo che sia causato dalla chiamata a os.system. Esiste un modo per eseguire altri file dallo script .pyw senza sollevare la finestra della console?Come evitare la finestra della console con il file .pyw contenente la chiamata os.system?

+0

Correlato: [Esecuzione di un processo in pythonw con Popen senza console] (http://stackoverflow.com/q/1813872/95735) –

+0

Credo che os.system() apra un NUOVO processo cmd. Prova os.execl() per SOSTITUIRE il nuovo processo cmd con il tuo processo pythonw.exe. – DevPlayer

risposta

5

Si potrebbe provare a utilizzare il modulo (subprocess.Popen, subprocess.call o altro) subprocess con l'argomento shell=True se si vuole evitare di iniziare una finestra di console.

+1

subprocess.check_call fa un buon sostituto per os.system in questo caso. – esm

+0

Ha funzionato ... Grazie! – twneale

+1

Assicuratevi di impostare 'subprocess.check_call (args, shell = True)' dove 'args' è la stringa di comando che dovrete digitare normalmente in una console. Non sono sicuro del perché 'shell = True' sia necessario quando non voglio che appaia una console, ma è quello che è successo nel mio esperimento. – Kit

13

Si dovrebbe usare subprocess.Popen classe che passa come esempio il valore del parametro di startupinfosubprocess.STARTUPINFO classe con l'attributo dwFlags tenendo subprocess.STARTF_USESHOWWINDOW bandiera e attributo wShowWindow tenendo subprocess.SW_HIDE bandiera. Questo può essere dedotto dalla lettura delle righe 866-868 del codice sorgente subprocess.py. Potrebbe essere necessario anche passare il flag subprocess.CREATE_NEW_CONSOLE come valore del parametro creationflags mentre si esegue sotto pythonw.exe che non apre una console.

Quando si utilizza shell=True succede solo che tutto quanto sopra è impostato correttamente ma ciò non significa che sia una soluzione adeguata. Direi che non è perché aggiunge sovraccarico di esecuzione dell'interprete dei comandi e degli argomenti di analisi. Inoltre, si tenga presente che (...) l'uso di shell = True è sconsigliato in modo corretto nei casi in cui la stringa di comando è costituita dall'ingresso esterno in base alla documentazione del modulo di sottoprocesso.

+0

L'input non proviene da un'origine esterna e non mi interessa il sovraccarico derivante dall'analisi del comando shell, soprattutto se evitarlo comporta la soluzione troppo complicata che descrivi sopra. – twneale

+1

L'uso di 'shell = True' non è la cosa giusta da fare qui e la (presunta) complessità della soluzione giusta non cambia questo. –

+2

Non posso credere che questa non sia la risposta più votata. Tutto perché le persone non possono essere disturbate a scrivere 3 righe di codice per fare le cose correttamente. +1 – hammus

13

La soluzione descritta da Piotr in realtà non è così complicata come potrebbe sembrare. Ecco un esempio in cui un startupinfo è passato ad un check_call invocazione per sopprimere la finestra della console:

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

subprocess.check_call(cmd, startupinfo=startupinfo) 

Dal momento che le funzioni comfort call, check_call e check_output avanti la loro **kwargs al costruttore Popen, non è necessario utilizzare Popen direttamente.

+0

-1: errore su Mac. – ArtOfWarfare

+2

@ArtOfWarfare Questa domanda è specifica per Windows, quindi non sorprende che possa avere esito negativo su altri sistemi operativi. Se vuoi aiutare, dovresti specificare l'errore esatto che ottieni su Mac OS. –

+0

È un lavoro elaborato (rispetto a quanto il codice è altrimenti necessario) in modo che un sistema (Windows) possa comportarsi come gli altri, ma nel processo interrompe gli altri. Vado con 'shell = true' - è breve, è dolce e funziona su tutte le piattaforme.Oh, e il problema su Mac (e suppongo * nix) è un'eccezione su 'STARTUPINFO()' non viene riconosciuto. – ArtOfWarfare

1

Sembra che "os.popen" non produca la finestra della console. Lo script è in esecuzione in "pythonw". Non sono sicuro di tutti i casi, ma nel mio caso funziona bene.

os.popen(command) 
7

Le persone sono un po 'pigro ... vorrei thx @Piotr Dobrogost e @Frank S. Tommaso per le loro risposte.

Sono venuto con questo codice che è runinng su Linux e Windows:

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 

tardi ...

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

ragazzi Thx;)

Inoltre: solo per notare che la il seguente codice che usa 'call' funziona anche su Python 2.7 (su Windows) con il codice 'STARTUPINFO' sopra:

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

Questo ha funzionato perfettamente per me, grazie. Non riesco a capire perché qualcuno vorrebbe usare shell = True, è solo un bug che aspetta di accadere. – Whatang

0

Simile a quello che @firsthand Detto questo, ho letto sul forum wxPython-utente che si "sostituire" l'applicazione in esecuzione in corso, che sarebbe "command.com" o "cmd.exe", con pyw.exe o pythonw.exe quando si utilizza qualcosa di simile al seguente:

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

vedere another post

Anche se non so come si condurrebbe io in questo caso.

Credo che un vantaggio di questo approccio è se si esegue lo script più volte la barra delle applicazioni del sistema operativo con non riempire con le icone CMD. In caso contrario, se nella barra delle applicazioni sono presenti diversi CMD ridotti al minimo e si inizia a chiuderli, è impossibile stabilire quale CMD supporta lo script pythonw.

Problemi correlati