Obtenir le code de sortie d'une application a commencé avec la “cmd” et “démarrer” commandes
J'ai une application console. L'Interaction avec cette application se fait via le protocole TCP/IP.
J'ai aussi un framework de test, ce qui est essentiellement une collection de scripts BATCH (...pas de ma faute). Ce que ce framework de test pour chaque test est essentiellement ceci:
start /min "myapplication.exe"
et attendre jusqu'à ce que la vérification est reçue que l'application est en cours d'exécution.- envoyer des commandes via TCP/IP à la présente demande, de recevoir ses réponses, et de vérifier si les horaires et les valeurs d'accord avec ce qui est prévu par le test spécifique.
Un problème que je rencontre actuellement est que l'application se ferme prématurément en raison d'une erreur interne. Je tient à faire la distinction entre l'échec des tests, et l'application de s'écraser. La seule indication que j'ai pour ce, qui est de l'application du code de sortie.
Donc, j'ai essayé le suivant:
start /min cmd /c "myapplication.exe || echo %errorLevel% > exitcode.txt"
et puis plus tard, dans les scripts de test,
if exist exitcode.txt (
set /p exitcode=<exitcode.txt
echo ERROR: myapplication.exe returned exitcode %exitcode%.
goto error
) else (
goto do_processing
)
mais pour une raison étrange, le fichier texte n'apparaît jamais, même si parfois, j'ai une boîte de dialogue à propos de l'application de s'écraser, et même si j'ai la force de le faire échouer avec un code de sortie non nulle. Le test va juste par do_processing
et (bien sûr) des résultats de l'échec.
MODIFIER
Quand je lance
start /min cmd /c "nonsense || echo %errorLevel% > test.txt"
Je parfois obtenir un fichier texte contenant la chaîne de caractères 9009, mais d'autres fois ce fichier texte contient la chaîne de caractères 0
, ou parfois 1
, ...qu'est-Ce...?!
EDIT2
Si vous tapez
cmd /k "nonsense || echo %errorLevel%"
(note de l' /k
option), à vous de voir 0
être imprimé dans la nouvelle fenêtre, mais si vous tapez echo %errorlevel%
, vous obtenez 1
....
Je savais que le lot n'était pas très sain d'esprit, mais il devrait au moins être constamment fou...
Toutes les idées sur ce qui pourrait se passer ici?
Passant: je pense que cela ne marchera pas, parce que si vous utilisez
start
le code de sortie ne sera pas transmis au script appelant. Vous devez utiliser call
à la place. Il se comporte comme start /wait
mais transmet des variables. Vérifiez ceci: stackoverflow.com/questions/13257571/...mais
start /wait
signifie l'exécution du script se bloque. Le script peut pas aller sur le feu commandes...J'ai appelé début (pour être en mesure à l'arrière-plan la tâche) en combinaison avec cmd (pour être en mesure de délivrer les 2 commandes; l'exécutable, en plus de l'écho que des sorties vers un fichier).
OriginalL'auteur Rody Oldenhuis | 2015-02-04
Vous devez vous connecter pour publier un commentaire.
Normal expansion comme
%errorLevel%
se produit lorsque la déclaration est analysée, et l'ensemble de la CMD /C de la ligne de commande est analysée en un seul passage, de sorte que la valeur que vous obtenez est la valeur qui existait avant que les commandes sont exécutées (toujours à 0).Vous pouvez obtenir une explication plus précise à https://stackoverflow.com/a/4095133/1012053. Il peut être difficile de suivre et de comprendre l'importance des phases au premier abord, mais cela en vaut la peine.
Pour résoudre votre problème, vous devez retarder l'agrandissement de la variable jusqu'après votre exe.
Vous avez deux options:
Option 1) Utiliser l'APPELER pour obtenir un retard à la ronde de l'expansion.
Dans un fichier de commandes vous permettront de doubler le pourcentage. Mais les commandes s'exécutent à l'aide de CMD /C sont exécutés en vertu d'une ligne de commande de contexte, pas de lot. Doubler le pourcentage ne fonctionne pas sous la ligne de commande.
Au lieu de cela, vous devez introduire un caret (cmd.exe caractère d'échappement) dans le nom de la variable. La première phase d'expansion se produit avant que les fuites sont traitées, de sorte qu'il ressemble à un nom avec l'accent circonflexe, et ne le trouve pas. Lorsqu'il n'est pas trouvé, la ligne de commande de l'analyseur conserve le texte original lorsque la variable n'est pas trouvé. Suivant les caractères spéciaux sont traitées et que la fuite est consommé. Ainsi, lorsque l'APPEL ronde de l'expansion se produit, il voit le bon nom de variable.
Je crois que vous émettez la commande de DÉMARRAGE à l'intérieur d'un script de commandes, de sorte que vous devez aussi le double du pourcentage empêcher le parent script de commandes de l'expansion de ERRORLEVEL.
Option 2) l'Utilisation d'une expansion retardée
Expansion retardée syntaxe est
!errorlevel!
au lieu de%errorlevel%
. Mais avant de pouvoir l'utiliser, l'expansion retardée doit être activé. Dans un script batch, vous utilisezsetlocal enableDelayedExpansion
, mais qui ne fonctionne pas dans une ligne de commande de contexte. Au lieu de cela, vous devez utiliser le cmd.exe/v:on
option.En supposant que votre script batch n'a pas permis une expansion retardée, ensuite, vous utilisez simplement la suivante:
Mais si votre script de commandes a permis l'expansion retardée, alors vous devez vous échapper de la
!
de sorte que le parent script batch ne pas étendre ERRORLEVEL. Notez que vous devez toujours utiliser/v:on
parce que la route sous-processus (normalement) la valeur par défaut désactivé expansion retardée.juste par curiosité: est-il un avantage/désavantage de
call
vscmd /v:on
?Dans ce cas, pas vraiment. L'APPEL est très lent, mais qui n'intervient que lorsque vous faites un nombre d'itérations dans une boucle serrée, - pas un problème ici. APPEL a également fait des ravages sur les cotés signes qui sont censés passer à travers (doubles), encore une fois pas un problème. Expansion retardée corrompt l'expansion de POUR les variables dont la valeur contient
!
caractère, pas un problème ici.Quelque chose est pas encore tout à fait comme il devrait...lorsque la condition se produit (crashs de l'application), le fichier texte est écrit dans les deux options, vous a donné. Cependant, avec l'option 1) il contient "
ECHO is on.
", et avec l'option 2) il contient "0
"...ne sais pas si ça compte, mais lestart
est appelée à partir d'unif (...)
, qui réside dans un fichier de commandes, qui estcalled
à partir d'un autre fichier de commandes, qui asetlocal EnableDelayedExpansion
OriginalL'auteur dbenham
Comme expliqué ici vous devez utiliser
call
au lieu destart
pour être en mesure d'évaluer les codes de sortie.call
va lancer le script dans le même variable d'environnement alors que les start (démarrer exécuter dans une nouvelle qui n'est pas accessible à partir de la première script.Vous pouvez écrire le code de sortie avec
@echo %errorlevel% >> output.txt
. Et c'est la raison pour laquelle vous ne pouvez pas utiliserstart
.start
de ne pas définir un accessible %errorlevel% dans le script d'appel. À l'aide destart
vous permet d'exécuter le test en arrière-plan, mais vous n'aurez pas accès au code de sortie.Oh, désolé, j'ai missunderstood vous.
C'est pourquoi je
start /min cmd /c "myapplication.exe || echo %errorLevel% > exitcode.txt"
. Puis commence uncmd
, avec ses propres variables d'environnement, qui exécute l'application et (sous certaines conditions) sorties code de sortie non nulle de fichier.Oui, désolé, le titre original était peut-être trompeuse.
OriginalL'auteur MichaelS
Une autre solution peut être d'utiliser
&
au lieu de||
La
^
est une évasion char, de sorte que ce est évalué à l'intérieur le début et non à l'extérieur comme expliqué ici.Cela a fonctionné pour moi. Espérons que cela aide quelqu'un.
OriginalL'auteur AxelWass