Comment l'invite de commande sait-elle quand attendre la sortie?

90

J'essayais de recoder une invite de commande Windows en C #. Je me demandais comment l'invite de commande sait quand attendre la fin du processus et quand ne pas attendre que le processus appelé se termine.

Par exemple, si vous tapez l'invite de commande "notepad", le Bloc - notes se lancera, mais vous pourrez toujours exécuter d'autres commandes. Cependant, si vous ouvrez un utilitaire tel que more.com, ping.exe ou un autre utilitaire, il attendra la fin du programme en cours d'exécution avant de vous permettre d'exécuter une autre commande.

Comment l'invite de commande sait-elle quand attendre la sortie et comment ce comportement peut-il être émulé en C #?

Justin Krejcha
la source
13
Excellente première question!
Rotem
2
Au niveau très basique, les programmes basés sur l'interface graphique sont appelés et l'exécution revient à l'invite. Cela pourrait être parce que le shell ne s'attend pas à ce que la commande interagisse avec lui?
shahkalpesh

Réponses:

122

Si l'application est une application GUI Win32, elle s'exécutera simplement et l'invite de commande n'attendra pas qu'elle se termine.

Si l'application est une application console, elle s'exécutera dans l'invite de commande et vous devrez attendre qu'elle se termine pour récupérer l'invite de commande.

ÉDITER:

D'ACCORD. Il semble que vous ayez besoin d'explications techniques. Si vous souhaitez émuler la même fonctionnalité dans votre application, vous pouvez vérifier les IMAGE_OPTIONAL_HEADERfichiers EXE ici .

À l'intérieur IMAGE_OPTIONAL_HEADER, il y a:

 WORD                 Subsystem;

If SubSystem == 0x02 cela signifie que c'est une application GUI.

If SubSystem == 0x03 cela signifie que c'est une application d'invite de commande.

MODIFIER 2:

Si vous voulez le voir en action:

  1. Télécharger http://www.ntcore.com/exsuite.php

  2. Copiez calc.exe ou notepad.exe sur votre bureau

  3. Ouvrez calc.exe copié dans CFF Explorer

  4. Accédez à En-têtes Nt -> En-têtes facultatifs

  5. Changer le sous-système de 0x002 à 0x003

  6. Sauvegarde le

Maintenant, exécutez le nouveau calcul modifié et vous verrez l'invite de commande attendre qu'il se termine.

72DFBF5B A0DF5BE9
la source
2
@SudhakarTillapudi, de rien, j'ai mis à jour la réponse avec plus de détails, j'espère qu'elle vous en expliquera plus.
72DFBF5B A0DF5BE9
3
c'est vraiment instructif encore une fois merci de rester me :)
Sudhakar Tillapudi
8

La valeur par défaut à partir d'une invite de commande est de générer le programme GUI dans un processus / fork séparé. Cependant, vous pouvez exécuter le bloc-notes (ou un autre programme GUI) en ligne avec votre invite de commande / script shell:

start /w notepad.exe

De cette façon, l'invite de commande / le script shell continue uniquement après la fin du processus notepad.exe.

J'espère que cela aide, TW

Tw Bert
la source
3

Lorsque vous démarrez un nouveau processus, une application GUI dans ce contexte qui fonctionne réellement en dehors des limites de l'invite, l'invite n'attendra pas. Mais, si vous exécutez une commande qui fonctionne entièrement sous les limites de l'instance actuelle d'une invite, elle attend.

Ainsi, la commande notepaddémarre simplement l'application Notepad et laisse le contrôle de l'application. Alors que, la commande ipconfigs'exécute sous un domaine (non ce n'est pas le domaine d'application ), de l'invite.

Pour généraliser extrêmement, lorsque vous utilisez Process.Startdans votre équivalent C #, n'attendez pas. Ce ne sera de toute façon pas le cas.

danois
la source