J'essaye d'exécuter un fichier batch en C #, mais je n'ai pas de chance de le faire.
J'ai trouvé plusieurs exemples de le faire sur Internet, mais cela ne fonctionne pas pour moi.
public void ExecuteCommand(string command)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.WaitForExit();
ExitCode = Process.ExitCode;
Process.Close();
MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
}
La chaîne de commande contient le nom du fichier de commandes (stocké dans system32
) et certains fichiers qu'il doit manipuler. (Exemple:) txtmanipulator file1.txt file2.txt file3.txt
. Lorsque j'exécute le fichier de commandes manuellement, cela fonctionne correctement.
Lors de l'exécution du code, cela me donne un **ExitCode: 1** (Catch all for general errors)
Qu'est-ce que je fais mal?
c#
batch-file
process
processstartinfo
Wessel T.
la source
la source
command
c'est. S'il contient des chemins avec des espaces, vous devrez les mettre entre guillemets.Réponses:
Cela devrait fonctionner. Vous pouvez essayer de vider le contenu des flux de sortie et d'erreur afin de savoir ce qui se passe:
* ÉDITER *
Compte tenu des informations supplémentaires contenues dans votre commentaire ci-dessous, j'ai pu recréer le problème. Il semble y avoir un paramètre de sécurité qui entraîne ce comportement (je n'ai pas étudié cela en détail).
Cela ne fonctionne si le fichier batch ne se trouve pas dans
C:\Windows\System32
. Essayez de le déplacer vers un autre emplacement, par exemple l'emplacement de votre exécutable. Notez que conserver des fichiers batch ou exécutables personnalisés dans le répertoire Windows est de toute façon une mauvaise pratique.* EDIT 2 * Il s'avère que si les flux sont lus de manière synchrone, un blocage peut se produire, soit en lisant de manière synchrone avant
WaitForExit
ou en lisant les deuxstderr
et de manièrestdout
synchrone l'un après l'autre.Cela ne devrait pas se produire si vous utilisez les méthodes de lecture asynchrones à la place, comme dans l'exemple suivant:
la source
cette simple ligne exécutera le fichier batch.
la source
Après une aide précieuse de steinar, voici ce qui a fonctionné pour moi:
la source
~%dp0
. Ajout duProcessInfo.WorkingDirectory
corrigé.command
si vous appelez directement le fichier BAT?command
paramètres peuvent être utilisés pour envoyer des arguments au fichier BAT, ce n'est pas ce que le code montre ici. Il n'est pas du tout utilisé en fait. Et si c'était le cas, il devrait probablement être nommé à laarguments
place.command
est utilisé dans l'new ProcessStartInfo
appel.Ça fonctionne bien. Je l'ai testé comme ceci:
J'ai commenté éteindre la fenêtre pour pouvoir la VOIR fonctionner.
la source
Voici un exemple de code c # qui envoie 2 paramètres à un fichier bat / cmd pour répondre à cette question .
Commentaire: comment puis-je passer des paramètres et lire le résultat de l'exécution d'une commande?
/ par @Janatbek Sharsheyev
la source
Le code ci-dessous a bien fonctionné pour moi
la source
la source
Avez-vous essayé de le démarrer en tant qu'administrateur? Démarrez Visual Studio en tant qu'administrateur si vous l'utilisez, car travailler avec des
.bat
fichiers nécessite ces privilèges.la source
Je voulais quelque chose qui soit plus directement utilisable sans valeurs de chaîne codées en dur spécifiques à l'organisation. Je propose ce qui suit sous forme de morceau de code directement réutilisable. L'inconvénient mineur est de devoir déterminer et transmettre le dossier de travail lors de l'appel.
Appelé comme ceci:
Dans cet exemple, à partir de Visual Studio 2017, dans le cadre d'une exécution de test, je souhaite exécuter un fichier de commandes de réinitialisation d'environnement avant d'exécuter certains tests. (SpecFlow + xUnit). J'étais fatigué des étapes supplémentaires pour exécuter manuellement le fichier bat séparément, et je voulais simplement exécuter le fichier bat dans le cadre du code de configuration du test C #. Le fichier batch de réinitialisation de l'environnement déplace les fichiers de cas de test dans le dossier d'entrée, nettoie les dossiers de sortie, etc. pour obtenir l'état de démarrage du test approprié pour le test. La méthode QuotesAround met simplement des guillemets autour de la ligne de commande au cas où il y aurait des espaces dans les noms de dossier ("Program Files", quelqu'un?). Tout ce qu'il contient est ceci: chaîne privée QuotesAround (string input) {return "\" "+ input +" \ "";}
J'espère que certains trouveront cela utile et gagneront quelques minutes si votre scénario est similaire au mien.
la source
Avec les solutions proposées précédemment, j'ai eu du mal à exécuter plusieurs commandes npm en boucle et à obtenir toutes les sorties sur la fenêtre de la console.
Cela a finalement commencé à fonctionner après avoir tout combiné des commentaires précédents, mais réorganisé le flux d'exécution du code.
Ce que j'ai remarqué, c'est que l'abonnement aux événements a été effectué trop tard (après le début du processus) et que certaines sorties n'ont donc pas été capturées.
Le code ci-dessous effectue maintenant les opérations suivantes:
Le code a été testé contre les blocages, bien qu'il soit synchrone (une exécution de processus à la fois), donc je ne peux pas garantir ce qui se passerait si cela était exécuté en parallèle.
la source
Utilisation de CliWrap :
la source
System.Diagnostics.Process.Start(BatchFileName, Parameters);
Je sais que cela fonctionnera pour le fichier batch et les paramètres, mais aucune idée sur la façon d'obtenir les résultats en C #. Habituellement, les sorties sont définies dans le fichier batch.
la source