Lancement d'un process DOS + Récupération de l'output [Résolu]

Messages postés
6
Date d'inscription
lundi 25 octobre 2004
Dernière intervention
21 mai 2007
- 18 mai 2007 à 15:44 - Dernière réponse :
Messages postés
2
Date d'inscription
mardi 13 janvier 2009
Dernière intervention
25 mai 2009
- 25 mai 2009 à 18:34
Salut,

je suis en train de programmer un outil permettant de lancer des processus de copie. Ces processus se servent en partie de XCOPY et d'autres API, toutes lancées via des commandes Dos.

Cependant, pour un confort d'utilisation, j'essaye de rendre transparent, pour les utilisateurs, l'utilisation de ces commandes Dos. Pour cela, je lance un processus via le code C#, et je récupère la StandardOutput, que je redirige vers une RichTextBox. Malheureusement, lorsque j'active la redirection du StandardOutput, le processus ne s'exécute plus du tout... Et je ne récupère pas non plus la sortie dans la RichTextBox.

Avant de poster, j'ai cherché sur les forums, et après moultes recherches et tentatives via des sources fournis, je me suis résigné à venir vous déranger...

Quelqu'un saurait-il pourquoi la redirection des messages de sortie ne fonctionne pas ? Et si oui, comment faire pour récupérer tout ça ?

Merci d'avance de votre aide !

Voici le code utilisé à l'heure actuelle :
//Lancement du process
process.StartInfo =
new
ProcessStartInfo(monappli,
arguments);
process.StartInfo.UseShellExecute =
false;
process.StartInfo.CreateNoWindow =
true;
process.StartInfo.RedirectStandardError =
true;
process.StartInfo.RedirectStandardOutput =
true;
process.OutputDataReceived +=
new
DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived +=
new
DataReceivedEventHandler(process_ErrorDataReceived);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
Afficher la suite 

Votre réponse

10 réponses

Messages postés
66
Date d'inscription
vendredi 20 octobre 2006
Dernière intervention
25 février 2008
- 18 mai 2007 à 16:31
0
Merci
??? Je recommence

Je ne sais pas comment utiliser les objets gérant l'outpout cela dit en DOS on peut rediriger le résultat d'une commande vers un fichier.

Une solution peu propre, car utilisant une écriture sur le disque, serait de rajouter "> logX.txt" (qui signifie écrire le résultat de la commande dans le fichier logX.txt, X étant le "numéro" de ta commande) à la fin de chacune de tes commandes dos
exemple : "ipconfig > ipconfig.txt" va créer (où écraser) le fichier ipconfig.txt et le remplir du résultat de la commande ipconfig
Ensuite tu peux lire le contenu de chacun des logs et l'ajouter à ta RichTextBox
Puis supprimer les log.

Il y a sûrement une meilleure solution.

Bonne journée

_Syl_
Commenter la réponse de cs__Syl_
Messages postés
6
Date d'inscription
lundi 25 octobre 2004
Dernière intervention
21 mai 2007
- 18 mai 2007 à 16:44
0
Merci
Salut !

En effet, j'avais pensé passer cette méthode, mais c'est pas très propre malheureusement. L'outil que je développe est pour une entreprise, je dois donc réussir à garder les temps d'exécution et la prise d'espace le plus bas possible.

J'envisagerai cette solution si et seulement si je n'arrive pas à trouver comment récupérer ce flux de sortie.

Merci pour ta réponse tout de même !

Fly.
Commenter la réponse de Fly95
Messages postés
6366
Date d'inscription
samedi 1 juin 2002
Dernière intervention
2 août 2014
- 18 mai 2007 à 18:32
0
Merci
Salut,

Pourtant le code en l'état devrait fonctionner...
Que fait tu dans les gestionnaires d'évènement ?
L'application lancée n'attendrais pas une saise de la part de l'utilisateur ?

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq
Messages postés
6
Date d'inscription
lundi 25 octobre 2004
Dernière intervention
21 mai 2007
- 18 mai 2007 à 20:20
0
Merci
Salut,

Ces lignes de code sont lancés lors d'un évènement click sur un bouton classique.
En gros, l'utilisateur régle ses variables via l'application csharp développée, puis, en me basant sur ces chaînes de caractères, je lance une commande XCOPY qui récupère des données à partir d'un serveur vers le poste client.

Aucun input n'est nécessaire de la part de l'utilisateur lorsque le processus se lance, puisque je passe directement la commande complète. De plus, lorsque j'effectue exactement les mêmes appels, sans rediriger la sortie, la fenêtre Dos s'ouvre et inscrit bien tous les fichiers copiés, les uns à la suite des autres.

Merci pour vos commentaires.
Je continue à chercher encore et toujours, mais je ne vois pas trop... Surtout que j'ai un code sur une autre application, qui fait exactement les mêmes appels, et qui fonctionne parfaitement !
Commenter la réponse de Fly95
Messages postés
6
Date d'inscription
lundi 25 octobre 2004
Dernière intervention
21 mai 2007
- 18 mai 2007 à 21:13
0
Merci
Ok, je vois ce dont tu parles.

J'ai utilisé des threads aujourd'hui et je vois la problématique ! Ca va pas être simple parce que j'ai encore un peu de mal avec les Threads, mais je vais y arriver.

L'important étant que le texte s'affiche "en temps réel" et pas d'un bloc, car l'utilisateur doit avoir du feedback pour connaître l'avancement de la copie.

Merci pour votre aide.
Commenter la réponse de Fly95
Messages postés
6366
Date d'inscription
samedi 1 juin 2002
Dernière intervention
2 août 2014
- 18 mai 2007 à 21:15
0
Merci
De rien :-)

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq
Messages postés
6
Date d'inscription
lundi 25 octobre 2004
Dernière intervention
21 mai 2007
- 21 mai 2007 à 18:22
0
Merci
Et... Je reviens à la charge !

Bon, c'est pas fameux fameux tout mon code, mais je commence à arriver à afficher quelquechose. Ce n'est malheureusement pas suffisant car il me semble que la moitié des informations "normalement" affichées par la commande Dos passent à la trappe...

Je pense que je dois utiliser un processus asynchrone pour récupérer les sorties de l'output et les afficher dans ma richTextBox. Cependant, je n'arrive pas à trouver d'exemples parlants pour me baser dessus.

Si quelqu'un avait l'amabilité de me fournir ça, je le suis en serais très reconnaissant.
Merci d'avance !
Commenter la réponse de Fly95
Messages postés
2
Date d'inscription
mardi 13 janvier 2009
Dernière intervention
25 mai 2009
- 25 mai 2009 à 17:23
0
Merci
Bonjour,
je m'excuse de remonter ce vieux sujet mais il me semble que c'est le sujet le plus proche que j'ai lu sur ce forum concernant mon probleme :
j'ai un problème concernant la lecture de la sortie standard d'un processus.

je me suis d'abord fortement inspiré de cette page http://jab.developpez.com/tutoriels/...ess/synchrone/ , ainsi que de la doc msdn pour la lecture syncrhone ou asynchrone mais je n'arrive pas à lire la sortie.


Donc pour revenir a mon programme, je lance un "process". durant
l'execution de ce processus la sortie standard evolue toute les
secondes. J'aimerai pouvoir enregistrer une de ces informations pour
faire évoluer une barre de chargement.


voila mes bout de code :

Code :
 
md = new MessageDialog (this, DialogFlags.DestroyWithParent,
MessageType.Info, ButtonsType.Cancel,"test","");

//on crée le thread de lecture des infos
Thread readInfo = new Thread(new ThreadStart(this.readOutput));

ProcessStartInfo processInfo = new ProcessStartInfo("povray");
processInfo.Arguments = InfoProj.getPathProj() + InfoProj.getNameProj() + ".ini";

//on déroute la sortie standard
processInfo.UseShellExecute = false;
processInfo.CreateNoWindow = true;
processInfo.RedirectStandardOutput = true;
outPov = new StringBuilder("");

povRender = new Process();
povRender.StartInfo = processInfo ;
// on utilise l'événement pour savoir quand le processus est terminé
povRender.EnableRaisingEvents = true ;
povRender.Exited += new EventHandler(this.renderEnded);
 
povRender.Start();

// on démarre le thread de lecture
readInfo.Start();
// on affiche la fenêtre de progression

md.Run();

// On vérifie si le processus est fini.
// Si ce n'est pas le cas, l'utilisateur a appuyé sur stop
// et il faut fermer le processus. Le thread est fermé après l'arrêt
// du processus
if( !povRender.HasExited)
{
povRender.Kill();
povRender.WaitForExit();
}
 
exitCode = povRender.ExitCode ;
System.Console.WriteLine(exitCode);

povRender.Close();
textviewMain.Buffer.Text = myString ;
 
protectedvoid renderEnded(object sender, EventArgs args){
 
md.Destroy();

}
 
privatevoid readOutput()
{
while(! povRender.HasExited)
{
StreamReader povOutPut = povRender.StandardOutput ;
myString += povOutPut.ReadLine();
}
}

 

voila, je ne vous met pas mon test de lecture asynchrone, la seul difference
est que, au lieu d'un thread de lecture j'ai un
DataReceivedEventHandler et j'utilise la fonction
beginOutputReadLine(). Je précise que je n'ai pas d'ereur a la
compilation ou l'execution mais je recupere indubitablement un string
vide, alors que la "sortie de l'application" de mon IDE me montre bien
les informations que je cherche a récupérer


par contre je n'ai pas tres bien saisie la difference entre lecture
synchrone de la sortie et lecture asynchrone. Dans mon cas laquelle me
conseilleriez vous ?


Je vous remercie d'avance pour vos reponses, en esperant avoir été le plus clair possible

Jerome
Commenter la réponse de zygou
Messages postés
2
Date d'inscription
mardi 13 janvier 2009
Dernière intervention
25 mai 2009
- 25 mai 2009 à 18:34
0
Merci
Re, désolé pour le double post mais je n'ai pas trouvé la fonction éditer ...
et bien j'ai un peu honte mais je ne récupère rien dans la sortie standard car mon processus n'écrit rien dans la sortie standard :s les information que je souhaite récupérer dans ce processus semble en faite redirigé vers la sortie de mon application ...
je ne comprend pas vraiment encore pourquoi mais je vais chercher de ce coté et je devrai resoudre mon probleme rapidement
je vous prie de m'excuser pour le dérangement
jerome
Commenter la réponse de zygou
Messages postés
6366
Date d'inscription
samedi 1 juin 2002
Dernière intervention
2 août 2014
- 18 mai 2007 à 20:49
-2
Merci
Tu utilises Invoke dans tes gestionnaires d'évènement ?
Si c'est le cas ça ne peut pas marcher en l'état, car dans le thread executant process_OutputDataReceived tu lances une opération dans le thread du GUI qui lui même ne peut effectuer le traitement comme il attend que le processus se ferme.
Et comme le thread appelant attend que Invoke soit terminé...
Tu vas devoir utiliser BeginInvoke au lieu de Invoke : dans ce cas là le texte ne s'affichera pas ligne par ligne mais intégralement à la fin du traitement, mais au moins le traitement en lui même ne sera pas bloqué.
Si tu veux que ton affichage soit mit à jour ligne par ligne, il va falloir que tu mettes en place un lancement du process dans un autre thread, et un mécanisme de synchronisation non bloquant pour le GUI.

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.