web-dev-qa-db-fra.com

Comment empêcher la commande Invite de se fermer après exécution?

Mon problème est que dans Windows, il existe des fenêtres en ligne de commande qui se ferment immédiatement après leur exécution. Pour résoudre ce problème, je veux que le comportement par défaut soit que la fenêtre reste ouverte. Normalement, ce comportement peut être évité avec trois méthodes qui me viennent à l’esprit:

  1. Mise en ligne d'une ligne pause après programmes batch pour inviter l'utilisateur à appuyer sur une touche avant de quitter
  2. Exécution de ces fichiers de commandes ou d’autres outils de manipulation de ligne de commande (même le démarrage, le redémarrage d’un service, etc. avec net start xy ou quelque chose de similaire) dans cmd.exe (Démarrer - Exécuter - cmd.exe)
  3. Exécuter ces programmes avec cmd /k comme ceci: cmd /k myprogram.bat

Mais il existe d'autres cas dans lesquels l'utilisateur:

  1. Exécute le programme la première fois et ne sait pas que le programme en question s’exécutera dans Invite de commandes (Processeur de commandes Windows), par exemple. lors de l’exécution d’un raccourci dans le menu Démarrer (ou ailleurs), OU
  2. C’est un peu inconfortable d’exécuter tout le temps cmd.exe et n’a pas le temps/l’opportunité de réécrire partout le code de ces commandes pour y mettre une pause ou éviter de quitter explicitement.

J'ai lu un article à propos du changement de comportement par défaut de cmd.exe lors de son ouverture explicite, avec la création d'une entrée AutoRun et la manipulation de son contenu à ces emplacements:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor\AutoRun

(Les éléments de l'exécution automatique sont _String values_...)

J'ai mis cmd /d /k comme valeur pour l'essayer, mais cela n'a pas du tout changé le comportement des éléments mentionnés ci-dessus ... Cela a simplement changé le comportement de la fenêtre de ligne de commande lors de son ouverture explicite (Start-Run -cmd.exe).

Alors, comment ça marche? Pouvez-vous me donner des idées pour résoudre ce problème?

53
Sk8erPeter

J'ai une solution qui ne peut s'appliquer que sur les fichiers .cmd et .bat:

Ouvrez regedit et accédez à chacun des éléments suivants:

[HKEY_CLASSES_ROOT\batfile\Shell\open\command]
[HKEY_CLASSES_ROOT\cmdfile\Shell\open\command] 

Modifiez maintenant la "valeur de clé par défaut" en cmd.exe /k "%1" %*. Désormais, chaque fenêtre de script batch restera ouverte après son exécution.

Notez que cela revient à utiliser cmd.exe /c cmd.exe /k program.bat, ce qui signifie qu'une autre instance CMD sera lancée dans celle parent. Je n'ai pas trouvé comment écraser le premier argument /c.

Vous pouvez également le faire avec [exefile], mais maintenant, une boîte de console vide apparaîtra si l'exécutable a une interface graphique.

26
user8228

Citation Microsoft :

Une console est fermée lorsque le dernier processus qui lui est associé s’achève ou appelle FreeConsole.

En d'autres termes, la fenêtre de la console Win32 sera toujours fermée lors de la fermeture du dernier programme exécuté à l'intérieur de celle-ci, ce qui ne peut pas être modifié.


(Pour les programmes MS-DOS 16 bits, Windows propose une option "Fermer à la fermeture" dans la boîte de dialogue des propriétés, mais il ne s'agit pas d'une exception au comportement ci-dessus: c'est le processus NTVDM qui maintient la fenêtre ouverte. Cette option est également à nouveau par programme.)

14
grawity

Il suffit d'ouvrir une invite de commande à l'emplacement de votre fichier de commandes et de saisir manuellement le nom de votre fichier de commandes pour l'exécuter dans cette fenêtre.

1. Accédez au dossier dans lequel réside votre exécutable.
2.Shift-clic droit et sélectionnez "Fenêtre de commande à partir d'ici"
3. Tapez le nom de l'exécutable et appuyez sur Entrée.
4.Le processus devrait s'exécuter, mais la fenêtre devrait rester ouverte

7
Lee Harrison

cmd.exe /k vous causera des problèmes avec un lot. Si le lot exit 1 (sans /B) votre console sera fermée. Une astuce consiste à utiliser:

cmd.exe /k cmd /c ...

Pour utiliser ceci par défaut pour tous les fichiers de traitement par lots, définissez HKEY_CLASSES_ROOT\cmdfile\Shell\open\command\(default) et HKEY_CLASSES_ROOT\batfile\Shell\open\command\(default) sur"%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*.

4
Wernight

Je viens de trouver une solution idiote après avoir lu la réponse de grawity.

Mon cas d'utilisation consistait à configurer un environnement de console au travail où toutes les solutions les plus raisonnables sont bloquées. Tout ce dont j'ai besoin est de définir PATH, de configurer des alias de doskey et d'être transféré dans le shell.

Ma solution (qui vient d’être testée sur Win7) ajoute add cmd en tant que dernière ligne du fichier de commandes. Ceci exécute une invite de commande imbriquée qui hérite de l'environnement de son parent. Ce Shell enfant maintient le processus de traitement par lots ouvert jusqu'à ce que vous SORTEZ. À ce stade, le traitement par lots n'a plus de processus enfants et se termine également.

3
kitsu.eb

Plutôt que d'utiliser PAUSE (je préfère CHOICE ou TIMEOUT que PAUSE si nécessaire), vous pouvez utiliser la solution ici: 886848/comment-faire-Windows-batch-fichier-pause-lorsque-double-cliqué } _.

Ainsi, si vous cliquez sur un fichier de commandes ou un lien (raccourci) à partir de l'Explorateur Windows, vous pouvez suspendre le programme de fichiers de commandes avant de le quitter afin de pouvoir afficher la sortie du programme et les messages d'erreur éventuels.

En utilisant CHOICE, vous pouvez programmer la possibilité pour l’utilisateur de sélectionner une série d’actions à effectuer, et en utilisant TIMEOUT, vous pouvez laisser la fenêtre se fermer après un certain délai (sans surveillance). Si vous exécutez le fichier de commandes à partir d'une fenêtre d'invite de commande, ces pauses peuvent être gênantes.

La solution liée vous permettra de décider si vous souhaitez ignorer les pauses si le fichier de traitement par lots a été exécuté à partir d'une fenêtre d'invite de commande.

Vous pouvez en lire plus sur le lien fourni, mais l’essentiel est qu’il utilise la variable d’environnement:

%cmdcmdline%

pour déterminer si le fichier de commandes a été exécuté à partir d’une fenêtre de commande ou non.

Donc, vous l'utilisez comme ceci:

Au moment où le fichier de commandes va se fermer, vous ajoutez du code comme celui-ci:

echo %cmdcmdline:"=-% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% NEQ 0 goto :EOF
pause
goto :EOF

rem if %errorlevel% EQU 0 batch-file: %~dpf0 was executed from Windows Explorer, ...
rem if %errorlevel% NEQ 0 batch-file: %~dpf0 was executed from within a Command Prompt
2
Kevin Fegan

Le meilleur moyen que j'ai trouvé pour contourner ce problème consiste à appeler vos fichiers de commandes à partir d'un autre fichier de commandes à l'aide de start.

donc, si vous exécutez normalement un fichier appelé go.bat, vous créerez un deuxième fichier batch nommé quelque chose comme go2.bat

le contenu de go2.bat serait juste

start go.bat

la première fenêtre se ferme immédiatement, mais celle qui exécute votre go.bat reste ouverte

1
agradl

Cela fonctionne pour la version 5.00 de l'éditeur de registre Windows.

[HKEY_CLASSES_ROOT\batfile\Shell\open\command]
@="cmd.exe /k \"%1\" %*"

[HKEY_CLASSES_ROOT\cmdfile\Shell\open\command]
@="cmd.exe /k \"%1\" %*"

Enregistrez les cmds ci-dessus dans un fichier appelé quelque chose comme cmdbatfile-open.reg et exécutez-le!

1
VumC

Supposons que vous souhaitiez lancer deux fichiers de commandes dans leur propre instance et que vous restiez ouverts si leurs exécutables se terminent. Permet d’appeler ces deux lots A.bat et B.bat.

Maintenant pour plus de simplicité, vous pourriez avoir un fichier de commandes pour les lancer tous les deux, appelons ce launch_both.bat avec le contenu suivant:

start cmd /k "A.bat & cmd /c"
start cmd /k "B.bat & cmd /c"

Cela pourrait ne pas fonctionner comme prévu si vous appelez exit dans l'un des deux fichiers de commandes. Cela devra être testé.

1
Francois

Pour les utilisateurs de Windows 10, notez qu'aucune des réponses ci-dessus ne fonctionne actuellement pour Windows 10.

Pour Windows 10, si vous avez accès au script, vous devez ajouter le code suivant à la fin:

read

Ce code attendra une entrée avant de fermer.

0
jaycode

En réponse au déclassement de PSIXO - "Cette réponse était déjà couverte dans la question. - Ro Yo Mi 20 janvier 2016 à 5:06" - NON, ce n'était PAS. Les réponses précédentes étaient: "pause", ce qui n'a pas fonctionné. La réponse de PSIXO était: "& pause", ce qui fonctionne. S'il vous plaît analyser plus attentivement avant de déclasser. J'ai lancé cela à partir d'une invite IDLE et cela a fonctionné:

    >>> os.system('dir ^ & pause')
    0
    >>> 

D'autre part:

    >>> os.system('dir ^ pause')
    1
    >>>

N'a PAS fonctionné (l'invite cmd a basculé et a en fait renvoyé une erreur (1)). Merci à PSIXO pour la réponse dont j'avais besoin. Henri.

0
Henry