Executer une commande et recuperer la sortie standard

Executer une commande et recuperer la sortie standard - C#/.NET managed - Programmation

Marsh Posté le 23-05-2007 à 10:41:26    

Salut a tous,
Bon je vous explique j'aimerais executer une commande et recuperer la sortie standard pour pouvoir l'afficher dans un label. J'ai créée la fonction suivantes mais ca ne marche toujours pas. Vous avez une idée pourquoi ca marche pas?
 
  public bool Execute(string executable, string arguments)
  {
   Process proc = new System.Diagnostics.Process();
   proc.StartInfo.FileName = executable;
   proc.StartInfo.Arguments = arguments;
   proc.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
   proc.StartInfo.RedirectStandardOutput = true;
   proc.StartInfo.UseShellExecute = false;  // <- C'etais demander pour pouvoir recuperer la sortie standard.
   proc.Start();
   lblConsole.Text += proc.StandardOutput.ReadToEnd();
   proc.WaitForExit();
   if (proc.ExitCode != 0)
    return false;
   return true;
  }


---------------
  ____
Reply

Marsh Posté le 23-05-2007 à 10:41:26   

Reply

Marsh Posté le 23-05-2007 à 11:40:10    

je dirais déjà de lire après le "waitforexit"


Message édité par MagicBuzz le 23-05-2007 à 11:40:18
Reply

Marsh Posté le 31-05-2007 à 14:12:45    

bon en fait j'ai trouver le probleme mais pas la solution. Ce que je veut faire c pouvoir lancer un programme en console et afficher le resultat dans un label sur une page aspx. Le probleme c que ca marche que si le programme a un temp d'execution relativement court genre  un "ping google.fr" fonctionne tres bien mais pas le programme que je veux lancer qui lui met plus de temps. J'ai cherché une facons d'augmenter le timeout pour que le programme ai le temp de s'executer, mais je n'ai rien trouver.
donc voila le code qui fonctionne pour un ping.
public bool Execute(string executable, string arguments)
{
 Process proc = new System.Diagnostics.Process();
 proc.StartInfo.FileName = executable;
 proc.StartInfo.Arguments = arguments;
 proc.StartInfo.RedirectStandardOutput = true;
 proc.StartInfo.UseShellExecute = false;
 proc.Start();
 
 lblConsole.Text += executable + " " + arguments;
 while (!proc.HasExited)
  lblConsole.Text += "<br>" + proc.StandardOutput.ReadLine();
 if(proc.ExitCode != 0)
  return false;
 return true;
}
 
Je sais pas si ca joue mais le label est dans une page ascx que j'appelle dans une autre page aspx, mais ca ne devrais pas venir de ca.
Si vous avez une idée n'hesiter pas.

Reply

Marsh Posté le 31-05-2007 à 14:15:42    

est ce qu'il existe un commande bash windows qui permet de lancer une appli en background comme sous linux pour que le processus continue de s'executer?
Je sais que dans ce cas je ne pourrais pas voir l'affichage mais bon si c le seul moyens de le faire.

Reply

Marsh Posté le 12-06-2007 à 14:22:39    

Plop !
 
J'ai aujourd'hui une question similaire.
 
Je veux pouvoir lancer un traîtement (ici un *.bat pour mes tests) qui peut prendre du temps. Je veux pouvoir récupérer à l'écran la sortie au fur et à mesure de son exécution. Notamment dans l'objectif de pouvoir interagir graphiquement avec le traîtement : un bouton annulé pour quitter le traîtement en cours, copier pour prendre la sortie dans le presse papier, etc.
 
Le problème, c'est que mon évènement "p_OutputDataReceived" ne tourne pas dans le même thread que mon TextBox1 et du coup je ne peux pas communiquer.
 
Avec un thread fabriqué "à la main", je sais comment jouer avec des delegate (enfin... je sais... y'a des exemples tous fais dans la MSDN :D) pour le faire, mais dans le cas d'un process je ne sais pas du tout... :sweat:
 

Code :
  1. private void Form1_Click(object sender, EventArgs e)
  2.        {
  3.            textBox1.Text = string.Empty;
  4.            ProcessStartInfo psi = new ProcessStartInfo("c:\\in\\test.bat" );
  5.            psi.CreateNoWindow = true;
  6.            psi.RedirectStandardOutput = true;
  7.            psi.UseShellExecute = false;
  8.            p = Process.Start(psi);
  9.            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
  10.            p.BeginOutputReadLine();
  11.            p.WaitForExit();
  12.            p.CancelOutputRead();
  13.            p.Close();
  14.        }
  15.  
  16.        private void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
  17.        {
  18.            textBox1.Text += e.Data;
  19.        }

Reply

Marsh Posté le 12-06-2007 à 15:46:08    

En utilisant un background worker avec un override du eventargs pour le déclenchement d'un  progress. tu lève un evnmt progress à chaque récupération de sortie afin de revenir dans le thread principal. Grâce au eventargs, tu peux récupérer les nouvelles valeurs à afficher dans ton textbox.
 
exemple ici : http://windowsclient.net/downloads [...] y1305.aspx


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
Reply

Marsh Posté le 12-06-2007 à 15:47:11    

euh... merci :jap:
 
rien pigé à ton explication, je vais regarder le lien :D

Message cité 1 fois
Message édité par MagicBuzz le 12-06-2007 à 15:47:21
Reply

Marsh Posté le 12-06-2007 à 15:56:47    

MagicBuzz a écrit :

euh... merci :jap:
 
rien pigé à ton explication, je fais regarder le lien :D


 
 
C'est simple, plutot que d'utiliser un Thread, (System.threading), utilise un Background worker. Ce dernier à la particularité de pouvoir retourner des évennements au thread appelant (typiquement le thread principal de ta fenêtre), à savoir , un evenement Progress et un évennement End, respectivement, un évennement que tu peux déclencher à tout moment dans ton "Thread" de backgroundWorker et un évennement de fin d'execution de la tâche "Threadée" de ton backgroundWorker.
 
Celui qui nous interesse le plus est l'evennement progress qui peux appeler un délégué dans le thread principal, celui ci remonte un evennement classique (object sender, progressEventArgs e). De base, le progressEventArgs ne propose qu'un entier de "progression" (une valeur entiere, un pourcentage de progression typiquement, que tu affecte dans ton traitement threadé à chaque 'Itération'). En surchargeant cet evenement pour pouvoir par exemple retourner un tableau de string, Cela te permet dans ton thread, d'instancier ton progressEventArgs en affectant les nouvelles chaines de caracteres dans le tableau et de le retourner au thread principal en déclenchant l'évennement.
 
 
Pour info, le background worker du framework 2.0 ne fait que simplifier des appels à des invoke/beginInvoke. Voici une simplification de son fonctionnement  
 
http://www.codeproject.com/csharp/workerthread.asp
 
 
 


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
Reply

Marsh Posté le 12-06-2007 à 17:39:45    

Merci beaucoup !
 
J'ai pondu ça... (pas eu trop le temps de me pencher dessus)
 
Ca marche, mais j'en suis pas trop content à cause des 3 lignes en commentaire... Le souci c'est que si je les mets pas en commentaire, mon thread fils attends que le thread père ait fini d'attendre le thread fils et... du coup ça freeze :D
 
FVaudra que je me penche un peu mieux dessus ce soir. En tout cas, c'est cool j'arrive à voir mon ping se dérouler tranquillement donc c'est un bon début.
 
Merci !
 

Code :
  1. using System;
  2. using System.Diagnostics;
  3. using System.Windows.Forms;
  4.  
  5. namespace Test
  6. {
  7.    public delegate void DelegateAddLine(string s);
  8.  
  9.    public partial class Form1 : Form
  10.    {
  11.        Process p;
  12.        public DelegateAddLine localDelegateAddLine;
  13.  
  14.        public Form1()
  15.        {
  16.            InitializeComponent();
  17.        }
  18.  
  19.        private void Form1_Click(object sender, EventArgs e)
  20.        {
  21.            textBox1.Text = string.Empty;
  22.            ProcessStartInfo psi = new ProcessStartInfo("c:\\in\\test.bat" );
  23.            psi.CreateNoWindow = true;
  24.            psi.RedirectStandardOutput = true;
  25.            psi.UseShellExecute = false;
  26.            p = Process.Start(psi);
  27.            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
  28.            p.BeginOutputReadLine();
  29.            //p.WaitForExit();
  30.            //p.CancelOutputRead();
  31.            //p.Close();
  32.        }
  33.  
  34.        private void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
  35.        {
  36.            IAsyncResult a = this.BeginInvoke(this.localDelegateAddLine, new Object[] { e.Data });
  37.            this.EndInvoke(a);
  38.        }
  39.  
  40.        private void Form1_Load(object sender, EventArgs e)
  41.        {
  42.            localDelegateAddLine = new DelegateAddLine(Form1_AddLine);
  43.        }
  44.  
  45.        private void Form1_AddLine(string line)
  46.        {
  47.            textBox1.Text += (line + "\r\n" );
  48.            textBox1.Focus();
  49.            textBox1.SelectionStart += textBox1.Text.Length;
  50.            textBox1.ScrollToCaret();
  51.        }
  52.    }
  53. }

Reply

Marsh Posté le 12-06-2007 à 17:42:32    

C'est pour cela que j'aurais plutot penché pour Lancer ton Batch DANS le thread d'un background worker ;)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
Reply

Marsh Posté le 12-06-2007 à 17:42:32   

Reply

Marsh Posté le 14-06-2007 à 11:22:46    

Plop, c'est moi que revoilà :D
 
Je viens de mettre en place la solution avec un backgroundworker (en fait, j'ai pigé tout à l'heure que c'est une class du framework :D)
 
Ca "marche", c'est à dire que mon script marche bien, et j'arrive bien à inter-agir avec ma form durant le traîtement.
 
Par contre là où ça déconne, c'est que je ne récupère rien dans mon StandardOutput ! :??:
 
En effet, sortie :


plop
 coin coin
yo


 
Code :

Code :
  1. Process ScriptProcess = null;
  2.        string cmdScript = string.Empty;
  3.        Form1 logFrm = null;
  4.  
  5.        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
  6.        {
  7.            foreach (ToolStripItem item in contextMenuStrip1.Items)
  8.            {
  9.                if (item.Selected && !string.IsNullOrEmpty(((Component)listView1.SelectedItems[0]).GetProertyValue(item.Text)))
  10.                {
  11.                    // Running the script...
  12.                    cmdScript = @"c:\in\test.bat";
  13.                    //cmdScript = ((Component)listView1.SelectedItems[0]).GetProertyValue(item.Text);
  14.                    this.backgroundWorker1.RunWorkerAsync();
  15.                    logFrm = new Form1();
  16.                    logFrm.textBox1.Text = "plop\r\n";
  17.                    logFrm.ShowDialog();
  18.                    break;
  19.                }
  20.            }
  21.        }
  22.  
  23.        private void RunScript()
  24.        {
  25.            ScriptProcess = new Process();
  26.  
  27.            // Setup
  28.            ScriptProcess.StartInfo.FileName = cmdScript;
  29.            ScriptProcess.StartInfo.CreateNoWindow = true;
  30.            ScriptProcess.StartInfo.UseShellExecute = false;
  31.            ScriptProcess.StartInfo.RedirectStandardError = true;
  32.            ScriptProcess.StartInfo.RedirectStandardOutput = true;
  33.  
  34.            // Set arguments
  35.            //ScriptProcess.StartInfo.Arguments = "/S /P /N /I /C:\"" + _stringToFind + "\" " + _filter;
  36.  
  37.            // Run
  38.            ScriptProcess.Start();
  39.  
  40.            // Get output
  41.            bool done = false;
  42.            string line;
  43.  
  44.            while (!done)
  45.            {
  46.                if (ScriptProcess.HasExited)
  47.                {
  48.                    done = true;
  49.                }
  50.  
  51.                // Get output
  52.                while (ScriptProcess.StandardOutput.Peek() > 0)
  53.                {
  54.                    try
  55.                    {
  56.                        line = ScriptProcess.StandardOutput.ReadLine();
  57.                        this.backgroundWorker1.ReportProgress(0, line);
  58.                    }
  59.                    catch (ArgumentException ex)
  60.                    {
  61.                        Debug.WriteLine(ex.Message);
  62.                    }
  63.                }
  64.  
  65.                // Look for errors too
  66.                while (ScriptProcess.StandardError.Peek() > 0)
  67.                {
  68.                    Debug.WriteLine(ScriptProcess.StandardError.ReadLine());
  69.                }
  70.  
  71.                // Wait if not done
  72.                if (!done)
  73.                {
  74.                    // Wait 1/10 a second
  75.                    ScriptProcess.WaitForExit(100);
  76.                }
  77.            }
  78.  
  79.            // Wait for exit
  80.            ScriptProcess.WaitForExit();
  81.  
  82.            // Reset
  83.            ScriptProcess = null;
  84.        }
  85.  
  86.        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  87.        {
  88.            RunScript();
  89.        }
  90.  
  91.        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
  92.        {
  93.            string line = e.UserState as string;
  94.  
  95.            logFrm.textBox1.Text += line + " coin coin\r\n";
  96.        }
  97.  
  98.        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  99.        {
  100.            //logFrm.Close();
  101.            logFrm.textBox1.Text += "yo";
  102.  
  103.        }


 
Le script :


dir c:\in\*.*
 
ping serveur1


 
Vu que j'ai bien "coin coin" qui apparaît, c'est qu'à priori, mon script se lance bien, et que je vais correctement lire mon standardoutput qui n'est pas vide...
De plus, le "yo" n'apparaît pas avant quelques secondes, ce qui correspond au temps nécessaire pour le ping... Bref, ça m'a l'air de marcher !
 
Sauf que... Bah j'ai rien comme résultat.
 
C'est quoi qui va pas encore ? :cry:

Reply

Marsh Posté le 14-06-2007 à 12:41:06    

Je viens de désactiver la récupération du standardoutput et faire tourner le script dans une fenêtre.
 
Comme je le pensais, il s'exécute pourtant bien et est verbeux comme prévu :sweat:
 
Mais pourtant je récupère rien dans mon programme :cry:

Message cité 1 fois
Message édité par MagicBuzz le 14-06-2007 à 12:41:35
Reply

Marsh Posté le 14-06-2007 à 15:00:54    

MagicBuzz a écrit :

Je viens de désactiver la récupération du standardoutput et faire tourner le script dans une fenêtre.
 
Comme je le pensais, il s'exécute pourtant bien et est verbeux comme prévu :sweat:
 
Mais pourtant je récupère rien dans mon programme :cry:


 
Désolé, là, je ne pourrais pas trop t'aider, j'avais deja fais ça il y a super longtemps mais j'ai plus trop le truc en tête.
 
Une petite recherche sur codeproject peut-être ?


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
Reply

Marsh Posté le 14-06-2007 à 15:10:26    

ixemul a écrit :

Désolé, là, je ne pourrais pas trop t'aider, j'avais deja fais ça il y a super longtemps mais j'ai plus trop le truc en tête.
 
Une petite recherche sur codeproject peut-être ?


le vrai problème, c'est que pourtant j'ai le même code que dans l'exemple qui marche !
 
c'est là en fait que je comprends pas pourquoi eux ça marche et moi ça marche pas :cry:
 
bon, vais creuser un peu

Reply

Marsh Posté le 14-06-2007 à 15:11:45    

MagicBuzz a écrit :

le vrai problème, c'est que pourtant j'ai le même code que dans l'exemple qui marche !
 
c'est là en fait que je comprends pas pourquoi eux ça marche et moi ça marche pas :cry:
 
bon, vais creuser un peu


 
Sans BackgroundWorker, ça marche ? (un simple Console.Writeline)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
Reply

Marsh Posté le 14-06-2007 à 15:36:22    

Bon, ben dans l'exemple ils passaient par un objet hérité de INotifyPropertyChanged pour raiser l'event Progress du BackgroundWorker, mais c'est pas ça...
 

Code :
  1. public class ScriptLine : INotifyPropertyChanged
  2.    {
  3.        private string line;
  4.  
  5.        public ScriptLine()
  6.        {
  7.            line = string.Empty;
  8.        }
  9.  
  10.        public ScriptLine(string Line)
  11.        {
  12.            line = Line;
  13.        }
  14.  
  15.        [Browsable(false)]
  16.        public string Line
  17.        {
  18.            get { return line; }
  19.            set
  20.            {
  21.                if (value != line)
  22.                {
  23.                    line = value;
  24.                    OnPropertyChanged(new PropertyChangedEventArgs("Line" ));
  25.                }
  26.            }
  27.        }
  28.  
  29.        #region INotifyPropertyChanged Members
  30.        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
  31.        {
  32.            if (null != this.PropertyChanged)
  33.            {
  34.                PropertyChanged(this, e);
  35.            }
  36.        }
  37.  
  38.        public event PropertyChangedEventHandler PropertyChanged;
  39.        #endregion
  40.    }


 
J'utilise ça à la place de ma simple String mais ça marche pas mieux :/

Reply

Marsh Posté le 14-06-2007 à 15:37:22    

ixemul a écrit :

Sans BackgroundWorker, ça marche ? (un simple Console.Writeline)


Je vais voir... J'en doute (si je colle des points d'arrêts, mais variables sont toujours vides)

Reply

Marsh Posté le 14-06-2007 à 15:40:30    

J'ai essayé avec un MessageBox.Show(line) et ça ne marche pas mieux (elle apparaît une fois, et vide)
 
Ligne 57 dans mon code

Reply

Marsh Posté le 14-06-2007 à 15:59:32    

Dans mon code, si aux lignes 29 à 32 j'inverse les valeurs booléennes.
Et que je commente les lignes 40 à 77, j'obtiens ça :
 
http://img519.imageshack.us/img519/7051/pingva2.png
=> Donc le script tourne bien.
 
Par contre, si je remets normalement et colle un point d'arrêt sur la ligne 56, le code n'y passe qu'une seule fois, et line = "", ce qui ne me semble pas normal du tout.
PAR CONTRE si en fin de script je colle un "copy c:\in\test.bat c:\in\test.old" j'ai bien un fichier qui se crée, donc le script s'exécute tout de même entièrement. Mais pour une raison totalement inconnue, je n'ai rien dans la sortie standard :(
 
Avec l'exemple (de ton premier lien) le point d'arrêt est visité plusieurs fois et line n'est jamais vide... :/
 
 
 
Si je fais "ReadToEnd()" au lieu de "ReadLine()" à la ligne 56, j'obtiens ça... à la fin de l'exécution (donc exécution synchrone, donc pas ce que je veux :fou:)


plop
 
C:\Users\MagicBuzz\Documents\Visual Studio 2005\Projects\NetAdmin\NetAdmin\bin\Debug>dir c:\in\*.*  
 Le volume dans le lecteur C s'appelle VistaOS
 Le num‚ro de s‚rie du volume est 1C5A-4296
 
 R‚pertoire de c:\in
 
12/06/2007  12:26    <REP>          .
12/06/2007  12:26    <REP>          ..
28/03/2007  10:59                 9 06000A01.csv
28/03/2007  10:59                 9 07001A05.csv
28/03/2007  10:59                 9 07100A10.csv
27/03/2007  15:44               339 folder.vbs
03/04/2007  14:06               934 genxfr.vbs
03/04/2007  14:08               567 genxfr.zip
16/05/2007  16:18    <REP>          gnxproadmin
04/06/2007  12:32    <REP>          invitation
28/03/2007  11:10             1ÿ358 MajCsv.vbs
03/04/2007  14:05             1ÿ036 SOC2000_321.spl
17/10/2006  10:15         3ÿ206ÿ878 taist.JPG
11/04/2007  15:25             8ÿ565 taist.png
14/06/2007  11:06                30 test.bat
11/04/2007  17:03             2ÿ404 test.xml
11/04/2007  17:05               660 test.xsl
12/04/2007  10:46             8ÿ087 trffou.sql
05/06/2007  15:08    <REP>          verif_ab
05/05/2007  09:25    <REP>          [Juuni Kokki][Les 12 royaumes][35 … 45][VoStFr] by Peret
              14 fichier(s)        3ÿ230ÿ885 octets
               6 R‚p(s)  32ÿ923ÿ426ÿ816 octets libres
 
C:\Users\MagicBuzz\Documents\Visual Studio 2005\Projects\NetAdmin\NetAdmin\bin\Debug>ping serveur1  
 
 
Envoi d'une requˆte 'ping' sur serveur1 [192.168.0.199] avec 32 octets de donn‚es :
 
 
 
R‚ponse de 192.168.0.199ÿ: octets=32 temps<1ms TTL=128
 
R‚ponse de 192.168.0.199ÿ: octets=32 temps<1ms TTL=128
 
R‚ponse de 192.168.0.199ÿ: octets=32 temps<1ms TTL=128
 
R‚ponse de 192.168.0.199ÿ: octets=32 temps<1ms TTL=128
 
 
 
Statistiques Ping pour 192.168.0.199:
 
    Paquetsÿ: envoy‚s = 4, re‡us = 4, perdus = 0 (perte 0%),
 
Dur‚e approximative des boucles en millisecondes :
 
    Minimum = 0ms, Maximum = 0ms, Moyenne = 0ms
 
 coin coin
yo


Message édité par MagicBuzz le 14-06-2007 à 16:09:47
Reply

Marsh Posté le 14-06-2007 à 17:18:48    

Bon, ben si quelqu'un n'a rien à foutre de la soirée, voici mon programme complet... Quand on fait un click droit sur l'icône et qu'on choisi une entrée dans le context menu, ça doit lancer le script "toto.bat" qui se trouve dans c:\in (à créer par vos soins).
 
Et dans la fenêtre qui s'ouvre, je suis censé avoir le mode verbeux du script, mais ça marche pas :cry:
 
http://membres.lycos.fr/magicbuzz/files/
 
Le fichier "NetAdmin.zip"


Message édité par MagicBuzz le 14-06-2007 à 17:20:02
Reply

Marsh Posté le 18-06-2007 à 11:06:52    

Bon, c'est encore moi...
 
C'est vraiment incompréhensible...
Si je met un point d'arrêt sur "while(!done)" ça marche sans problème : ça affiche bien la progression du script, et en temps réel comme désiré (à chaque fois que je fais "F5" ça m'affiche effectivement ce qu'il s'est passé entre temps)
 
Mais si je ne fais pas de point d'arrêt, ça fait que dalle :(

Reply

Marsh Posté le 18-06-2007 à 11:21:24    

Total n'importe quoi...
 
Si j'ajoute des Debug.WriteLine(), selon où je les met, ça marche ou ça marche pas... Ou même ça marche à moitié (ça affiche le résultat de la première instruction de mon script - un dir *.* - mais pas la seconde - un ping - que je peux quand même récupérer à l'aide un "ScriptProcess.StandardOutput.ReadToEnd()" juste avant de détruire mon objet :fou:
 
Putain mais ça me gave c'est quoi ce bordel encore ? Un bug du framework ou quoi ???

Reply

Marsh Posté le 18-06-2007 à 11:59:24    

Bon, j'ai trouvé une parade.
 
Visiblement "Peek()" c'est de la merde en branche daubé jusqu'à la dernière ligne, donc :
 

Code :
  1. private void RunScript()
  2.        {
  3.            ScriptProcess = new Process();
  4.  
  5.            // Setup
  6.            ScriptProcess.StartInfo.FileName = cmdScript;
  7.            ScriptProcess.StartInfo.CreateNoWindow = true;
  8.            ScriptProcess.StartInfo.UseShellExecute = false;
  9.            ScriptProcess.StartInfo.RedirectStandardError = true;
  10.            ScriptProcess.StartInfo.RedirectStandardOutput = true;
  11.  
  12.            // Set arguments
  13.            //ScriptProcess.StartInfo.Arguments = "/S /P /N /I /C:\"" + _stringToFind + "\" " + _filter;
  14.  
  15.            // Run
  16.            ScriptProcess.Start();
  17.  
  18.            // Get output
  19.            bool done = false;
  20.            string line;
  21.            ScriptLine sl;
  22.  
  23.            while (!done)
  24.            {
  25.                if (ScriptProcess.HasExited)
  26.                {
  27.                    done = true;
  28.                }
  29.                
  30.                // Get output
  31.                line = ScriptProcess.StandardOutput.ReadLine();
  32.                while (line != null)
  33.                {
  34.                    try
  35.                    {
  36.                        sl = new ScriptLine(line);
  37.                        this.backgroundWorker1.ReportProgress(0, sl);
  38.                        line = ScriptProcess.StandardOutput.ReadLine();
  39.                    }
  40.                    catch (ArgumentException ex)
  41.                    {
  42.                        Debug.WriteLine(ex.Message);
  43.                        break;
  44.                    }
  45.                }
  46.  
  47.                // Look for errors too
  48.                line = ScriptProcess.StandardError.ReadLine();
  49.                while (line != null)
  50.                {
  51.                    Debug.WriteLine(line);
  52.                    line = ScriptProcess.StandardError.ReadLine();
  53.                }
  54.                
  55.                // Wait if not done
  56.                if (!done)
  57.                {
  58.                    // Wait 1/2 a second
  59.                    ScriptProcess.WaitForExit(500);
  60.                }
  61.            }
  62.  
  63.            // Wait for exit
  64.            ScriptProcess.WaitForExit();
  65.  
  66.            // Reset
  67.            ScriptProcess = null;
  68.        }


 
Les bonnes grosses méthodes de VBistes sont toujours les meilleurs : les plus crades, mais qui marchent :o


Message édité par MagicBuzz le 18-06-2007 à 12:01:05
Reply

Marsh Posté le 18-06-2007 à 12:16:40    

http://jab.developpez.com/tutoriel [...] synchrone/
 
Ca m'a l'air plus simple sa méthode à lui...
 
VIII. Récupérer des informations affichées par le processus externe
-B. En utilisant un thread

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed