c # - Læs fra konsolprocessen

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en proces, jeg kan starte og skjule arbejde fint, men jeg vil læse fra konsolprogrammet, når jeg kører, ikke efter, jeg har forsøgt at køre en timer, og læses ved krydset, men mit program går bare ned og når det ikke gør, får jeg intet overhovedet.


            startInfo= new ProcessStartInfo("cmd.exe");
            startInfo.Arguments ="/C uus.exe "+ arg.ToString();
            startInfo.RedirectStandardError = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.UseShellExecute = false;
            startInfo.CreateNoWindow = true;
            this.timer1.Enabled=true;
            this.listBox1.Items.Clear();
            p= Process.Start(startInfo);
                            Application.DoEvents(); 

        void Timer1Tick(object sender, EventArgs e)
    {
        string str="";
        str=p.StandardOutput.ReadLine();
        if(str != null)
        {
            this.Text=str.ToString();
            this.listBox1.Items.Add(str);
        }
        Application.DoEvents();
    }


Så hvad gør jeg for at løse dette?





Opdatering:
Jeg prøvede bender forslag
nu kolliderer mit program ikke længere, men får heller ikke nogen data


            proc.StartInfo.UseShellExecute=false;
            proc.StartInfo.CreateNoWindow=true;
            proc.StartInfo.RedirectStandardOutput=true;
            proc.StartInfo.RedirectStandardError=true;
            proc.StartInfo.FileName="uus.exe";
            proc.StartInfo.Arguments=arg;
            proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(SortOutputHandler);
            proc.Start();
            proc.BeginOutputReadLine();

    void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
    {
        string str="";
        string str2="";
        str=e.Data.ToString();
        if(str!=null && str!="")
        {
            this.listBox1.Items.Add(str.ToString());
            this.Text=str.ToString();
        }
        str2=proc.StandardOutput.ReadLine();
        if(str2!=null && str2!="")
        {
            this.lsw1.Items.Add(str2.ToString());
        }
    }


hmm?





Opdatering:
Jeg har ændret handleren, fordi jeg har fortalt det, kan det ikke gøre det, at det vil være cross thread operation, usualyy jeg vil have en fejl, hvis det var.


private delegate void TextAdderDelegate(string str);

void TextAdder(string str)
{
   if(this.lsw1.InvokeRequired==true)
   {
      Invoke(new TextAdderDelegate(TextAdder),new object[] {str});
   }
   else
   {
      this.lsw1.Items.Add(str);
   }
}

void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
{
   string str="";

   if(e!=null)
   {
      if(e.Data!=null)
      {
         str=e.Data.ToString();
      }
   }
   TextAdder(str);
}

Bedste reference


Problemet er, at du kører på en tråd og forsøger at skrive ved hjælp af en anden. Når du har oprettet din baggrundstråd ved hjælp af Timer's tick event, kan den ikke have frontend-brugerindgang.


Måske hvis du forklarede det store billede af, hvad du forsøger at opnå, kan vi bedre hjælpe dig.


I mellemtiden vil du måske oprette Threadsafe-skrifter. Denne artikel hjælper dig med at forstå problemet og løsningen på at skrive for at danne kontroller på forskellige tråde. [9]

Andre referencer 1


Du kan muligvis oprette proceseksemplet eksplicit (f.eks. new Process) og bruge OutputDataReceived hændelsen, metoden BeginOutputReadLine() og, når du er færdig CancelOutputRead() for det.


Begivenheden OutputDataReceived bliver gentagne gange kaldet asynkront fra en anden tråd , så snart outputdata er tilgængelige.

Andre referencer 2


Jeg går ud fra, at du får en 'trådkors undtagelse', det kan skyldes, at du opdaterer dine formularkontroller på en anden tråd end brugergrænsefladen.