Comment empêcher l'invite de commande de se fermer après l'exécution?


55

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. Mettre une pauseligne après les 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 xyou quoi que ce soit de similaire) dans cmd.exe(Démarrer - Exécuter - cmd.exe)
  3. Exécuter ces programmes avec cmd /kcomme ceci: cmd /k myprogram.bat

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

  1. Exécute le programme pour la première fois et ignore que le programme en question sera exécuté à l’invite de commande (processeur de commande Windows), par exemple lors de l’exécution d’un raccourci à partir du menu Démarrer (ou ailleurs), OU
  2. Il est un peu inconfortable d’exécuter tout le temps cmd.exe et n’a pas le temps / l’opportunité de réécrire le code de ces commandes partout pour les mettre en pause ou éviter de quitter explicitement.

J'ai lu un article sur la modification du comportement par défaut cmd.exelors de son ouverture explicite, avec la création d'une entrée d'exécution automatique 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 AutoRun sont _String values_...)

J'en ai fait cmd /d /kune valeur pour l'essayer, mais cela n'a pas du tout changé le comportement des éléments mentionnés ci-dessus ... Cela a juste 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?


10
Votre question avec toutes les explications donnait envie à ma tête d’exploser. Pouvez-vous dire quelque chose comme: je veux exécuter un fichier de commandes avec cette commande "exemple" et je veux que la boîte de commande reste ouverte une fois l'opération terminée. Est-ce ce que vous demandez? S'il vous plaît mettre dans un échantillon proche du code.
KCotreau

1
+1 d'accord. Un peu pour commenter, veuillez reconsidérer votre question et, si possible, utilisez un exemple et rédigez une question plus succincte.
Type de slot

2
C'est un comportement normal, et bien que votre question soit certainement valable, vous devriez vous demander pourquoi vous devez laisser l'invite de commande ouverte après (la plupart des utilitaires sont créés avec cette mise en garde à l'esprit).
Breakthrough

1
A mon avis, ce n'est pas une vraie question. Comme vous venez d'instruire l'utilisateur à utiliser un fichier de commandes à la place. Si ce n'est pas le but de la question, clarifiez-la en supprimant toute information confuse et en expliquant quel est votre véritable objectif. Il est difficile de trouver la bonne réponse si ce n'est pas clair ...
Tamara Wijsman

1
@Randolf Richardson, qui est parce que ces outils ne sont pas censés être vu par un utilisateur final jamais (après tout, c'est pourquoi nous utilisons maintenant des interfaces graphiques). Si vous avez besoin de ces informations, la plupart des groupes informatiques vous enverront des fichiers de commandes pour rassembler les informations système appropriées et les afficher. Je ne vois pas comment il est possible que si une solution à cette question est trouvée, cela causera moins de problèmes que si elle résout - tant de choses sont envoyées de stdoutmanière constante et n'ont jamais été supposées être visibles pour une bonne raison.
Percée le

Réponses:


27

J'ai une solution qui ne peut s'appliquer que sur .cmdet les .batfichiers:

Ouvrir regeditet aller à chacun de:

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

Maintenant, changez 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 /cargument.

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.


4
+1 pour avoir ici la seule solution qui réponde réellement à la question posée. Malheureusement, je pense que cela pourrait être une fuite de mémoire en attente. Que se passe-t-il lorsqu'un service lance un nouveau fichier de commandes sans spécifier CMD.EXE dans la ligne CMD? Ce code ne sera-t-il pas utilisé dans ce cas? Cela ne va-t-il pas créer une nouvelle fenêtre sur un bureau non interactif et le laisser ouvert jusqu'au redémarrage?
Krowe2

@APerson Votre modification a cassé la commande en n'incluant pas le *. S'il vous plaît soyez plus prudent lors de l'édition!
not2qubit

@ not2qubit Désolé, je n'ai pas remarqué que j'ai supprimé trois astérisques au lieu de deux. Ça ira.
Après

17

Citation Microsoft :

Une console est fermée lorsque le dernier processus attaché à celle-ci se termine 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 que vous ne pouvez pas modifier.


(Pour les programmes MS-DOS 16 bits, Windows propose une option "Fermer à la sortie" 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.)


13
+1 pour comprendre comment et pourquoi les fenêtres de la console se ferment (contrairement à la plupart des personnes qui disent simplement "OMG POURQUOI NE PEUT-IL PAS Rester OUVERT !!!!!!!!!!! 1111one"). Il se comporte comme prévu et devrait rester ainsi à mon humble avis. C'est la raison principale pour laquelle nous avons des flux standard et des fichiers de commandes.
Percée

27
@ Breakthrough La question est How can I do X, pas In your opinion, should I do X. Cette réponse est inutile, cela implique que X est impossible, lorsque des solutions partielles ont déjà été présentées ailleurs. (-1)
Superbest

8

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 contenant votre exécutable
2. Maj-clic droit et sélectionnez "Fenêtre de commande à partir d'ici"
3. Saisissez le nom de l'exécutable et appuyez sur Entrée
. Le processus doit s'exécuter, mais la fenêtre doit rester ouverte.


1
Je ne connaissais pas Shift + clic droit. Cependant, vous pouvez aussi glisser-déposer le fichier exe dans une fenêtre de commande, ce qui met automatiquement le chemin à votre place.
Superbest

1
Cela fonctionne généralement pour moi, mais ce n'est apparemment pas une chose sûre, car je cherche ici une solution précisément parce que cela ne fonctionne pas dans ma situation actuelle.
RenniePet

c'est la solution la plus facile et doit être marquée comme la bonne réponse
Vicky Kapadia

4

cmd.exe /kvous donnera des ennuis 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 commandes, 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" %*.


1
Je pensais que cela "%*"passe la liste complète des paramètres, alors cela ne passerait-il pas le premier paramètre deux fois, une fois au fur "%1"et à mesure comme premier paramètre de "%*"?
Kevin Fegan

1
@KevinFegan Je n'ai pas vérifié la raison, mais% 1 devrait conserver les guillemets, ce qui signifie que, dans certains cas, il serait peut-être double. Il y a aussi une différence entre %1 %2 %3 ..et %*dont je ne me souviens pas pour l'instant, mais cela %1 %2 %3fonctionne dans certains cas où %*échoue.
Wernight le

3

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

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) s’ajoute cmdà la 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.


2

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 diverses 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

1

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


Cela fonctionne, je viens de mettre le nom de l'exécutable d'invite de commande dans un fichier bat (1.bat) appelé à l'aide de la commande start à partir d'un deuxième fichier bat "start 1.bat". La fenêtre de commande reste ouverte.
ejectamenta

1

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.reget exécutez-le!


2
Bienvenue sur Stack Exchange! J'ai corrigé le formatage dans votre réponse pour vous. Voir ici pour l'aide au formatage. De plus, lorsque vous publiez un code, n’oubliez pas d’expliquer ce qu’il fait exactement. Vous voudrez peut-être aussi lire la marche à suivre pour répondre .
Blacklight Shining

1

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.batet B.bat.

Maintenant, pour plus de simplicité, vous pourriez avoir un fichier batch pour les lancer tous les deux, appelons cela launch_both.batavec le contenu:

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 l' exitun des deux fichiers de commandes. Cela devra être testé.


0

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.


Rappelez-vous que la question avait été posée avant Windows 10 (il y a 5 ans), veuillez éditer votre réponse avec davantage d'informations
lundi

0

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 exécuté ceci à 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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.