12
votes

Comment éviter la fenêtre de la console avec un fichier .pyw contenant un appel OS.System?

Si je registre mes fichiers de code sous forme .pyw , aucune fenêtre de console n'apparaît - qui est ce que je veux - mais si le code comprend un appel sur OS.System , Je reçois toujours une fenêtre de la console Pesky. Je suppose que c'est causé par l'appel à OS.System . Existe-t-il un moyen d'exécuter d'autres fichiers de mon .pyw sans augmenter la fenêtre de la console du tout?


2 commentaires

Connexes: exécution d'un processus à Pythonw avec popen sans console


Je crois que OS.System () ouvre un nouveau processus CMD. Essayez OS.Execl () pour remplacer le nouveau processus CMD par votre processus Pythonw.exe.


6 Réponses :


6
votes

Vous pouvez essayer d'utiliser l'utilisation du sous-processus module ( subprocess.popen < / code>, sous-processus.call ou autre) avec l'argument shell = true si vous souhaitez éviter de démarrer une fenêtre de la console.


7 commentaires

Subprocess.Check_Call fait un bon remplacement pour OS.System dans ce cas.


Assurez-vous de définir sous-processus.check_call (args, shell = true) args est la chaîne de commande que vous saisiriez habituellement une console. Je ne sais pas pourquoi shell = true est nécessaire lorsque je ne veut pas vouloir qu'une console apparaisse, mais c'est ce qui est survenu dans mon expérience.


En effet; SUBPROCESS.POPEN (...) Ouvrira une fenêtre de la console, SUBPROCESS.POPEN (..., Shell = TRUE) N'ouvrira pas une fenêtre de console. Ma conviction est que, avec shell = true il est exécuté dans le sous-système du processus en cours --- qui sera "fenêtre" plutôt que "console" pour pythonw --- que d'être lancé entièrement séparément, où étant un sous-système de console exécutable, il ouvrira une nouvelle fenêtre de console.


J'ai amélioré la réponse pour être plus précise et plus précise sur ce qui a besoin de faire.


@Chrismorgan ma croyance est (...) Je pense que ce n'est pas ce qui se passe. En fait avec shell = true chaque sous-processus ouvre sa propre console mais elle est cachée. Voir Démarrage Paramètre, Subprocess.Create_New_Console drapeau, Subprocess.Startupinfo.wshowwwindow attribut et Cette ligne de subprocess.py .


shell = true n'est pas nécessaire ici. Consultez ma réponse et ma réponse Comment éliminer les consoles de Windows des processus générés dans Python (2.7)?


@PIODRDOBROGOST: Vous avez absolument raison. J'avais oublié que j'avais écrit cela ou je l'aurais corrigé - j'avais l'occasion de rencontrer la vraie explication plus tôt cette année. Merci d'avoir offert la correction!



15
votes

Vous devez utiliser subprocess.popen classe passant comme < Code> STARTUPINFO SUPPÈME DE VALEUR DES PARAMÈTRES DE SUBPROCESS.STARTUPINFO Classe avec DWFLAGS Attribut Holding Subprocess.Starf_USESHOWWINDOW drapeau et wshowwindow attribut Holding sous-processus.sw_hide Drapeau. Ceci peut être déduit de lignes de lecture 866-868 de sous-processus. py code source. Il pourrait également être nécessaire de transmettre sous-processus.create_new_console drapeau comme valeur de créationflags Paramètre lorsque vous exécutez sous pythonw.exe < / code> qui n'ouvre pas une console.

Lorsque vous utilisez shell = true il arrive que tout ce qui précède soit défini correctement, mais cela ne signifie pas que c'est une solution appropriée. Je dirais que ce n'est pas parce que cela ajoute des frais généraux d'interprète de commande et d'analyse des arguments. De plus, vous devez garder à l'esprit que (...) l'utilisation de coquille = true est fortement découragé dans des cas où la chaîne de commande est construite à partir d'une entrée externe selon la documentation du module de sous-processus.


4 commentaires

L'entrée n'a pas été issue d'une source externe et je ne me soucierai pas de plus en plus sur les frais généraux de l'analyse de la commande shell, surtout si l'évitez de l'éviquer de la solution surpliquée que vous décrivez ci-dessus.


En utilisant shell = true n'est pas la bonne chose à faire ici et la complexité (présumée) de la bonne solution ne change pas cela.


Je ne peux pas croire que ce n'est pas la meilleure réponse votée. Tous parce que les gens ne peuvent pas être dérangés d'écrire 3 lignes de code afin de faire les choses correctement. +1


Pouvez-vous également ajouter un exemple?



13
votes

La solution que Piotr décrit n'est pas aussi compliquée que possible. Voici un exemple où un StarTupinfo est transmis à un Check_Call Invocation pour supprimer la fenêtre de la console: xxx

puisque les fonctions de commodité appelez , check_call et check_output Transférer leur ** kwargs au popen constructeur, il n'est pas obligé d'utiliser popen directement.


3 commentaires

@Artofwarfare Cette question est spécifique à Windows. Il n'est donc pas surprenant que cela puisse échouer sur d'autres systèmes d'exploitation. Si vous souhaitez vous aider, vous devez indiquer l'erreur exacte que vous obtenez sur Mac OS.


C'est un travail élaboré autour (par rapport à la quantité de code autrement nécessaire) afin qu'un système (Windows) puisse se comporter de la même manière que les autres, mais dans le processus enfreint les autres. Je vais avec shell = true - c'est court, c'est doux, et ça marche sur toutes les plateformes. Oh, et le problème sur Mac (et je suppose * Nix) est-il jette une exception sur startupinfo () non reconnu.


@Artofwarfare 1. Il n'est pas élaboré car ce n'est que 3 lignes supplémentaires simples en comparaison à shell = true - startupinfo = subprocess.startupinfo (); startupinfo.dwflags | = _subprocess.starf_useshowwindow; startupinfo.wshowwindowwindow = _subprocess.sw_hide) . 2. Sa Windows spécifique et, en tant que telle, ne doit être appliqué que sur Windows. Pour cette raison, parler de Briser d'autres systèmes n'a pas de sens.



1
votes

Il semble que 'OS.Popen' ne produise pas la fenêtre de la console. Le script fonctionne sous 'pythonw'. Pas sûr de tous les cas, mais dans mon cas, cela fonctionne bien.

os.popen(command)


0 commentaires

7
votes

Les gens sont un peu paresseux ... je serais merci @piotr Dobrogrogosost strong> et @frank S. Thomas strong> pour leurs réponses.

Je suis venu avec ce code qui Runinng est exécuté sur Linux et Windows: p> xxx pré>

plus tard ... p> xxx pré>

thx gars;) p> En outre: juste pour noter que le code suivant à l'aide de "appel" fonctionne également sur Python 2.7 (sous Windows) avec le code "StartUpinfo" ci-dessus: P>

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


1 commentaires

Cela a parfaitement travaillé pour moi, merci. Je ne comprends pas pourquoi quelqu'un voudrait utiliser Shell = TRUE, c'est juste un bug qui attend de se produire.



0
votes

similaire à ce que @firstthand a dit, j'ai lu sur les forums d'utilisateur WXPython que vous avez "remplacer" l'application actuelle exécutée, qui serait "Command.com" ou "CMD.EXE ", avec pyw.exe ou pythonw.exe lorsque vous utilisez quelque chose comme ce qui suit: xxx

voir Un autre message

Bien que je ne sais pas comment tu conduisiez IO dans ce cas.

Je pense qu'un bénéfice de cette L'approche est que si vous exécutez votre script plusieurs fois votre barre des tâches OS sans remplir avec des icônes CMD. L'inverse si vous avez plusieurs cmd minimisés dans la barre des tâches et commencez à les fermer, il est impossible de dire quelle cmd va avec quel script Pythonw.


0 commentaires