2009-06-11 4 views
1

나는 프로세스를 시작할 수 있고 잘 동작하는 것을 숨길 수 있지만 콘솔 프로그램에서 읽으 려 할 때, 실행 후, 실행하지 않고, 타이머를 실행하려고 시도했다가 틱에서 읽었을 때 ,하지만 내 프로그램은 그냥 충돌하고하지 않을 때, 나는 아무것도 얻지 못한다.콘솔 프로세스에서 읽음

  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(); 
    } 

그럼 어떻게해야합니까?


업데이트 : 나는 지금 내 프로그램이 더 이상 충돌하지 않는 벤더 제안 을 시도뿐만 아니라 모든 데이터

  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()); 
     } 
    } 

흠을 recvie하지 ?


업데이트 : 나는 내가 말할 인 때문에, 그것이 크로스 스레드 작업, 줘야 것을, 그것을 할 수 처리기를 변경 한 usualyy 내가 WILLE이 그것이 경우 오류가 발생합니다.

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); 
} 
+0

나는 또한 cmd를 쓰지 않고 프로세스를 직접 실행하려고 시도했다. –

답변

1

문제는 하나의 스레드에서 실행 중이고 다른 스레드를 사용하여 쓰려고한다는 것입니다. 타이머 틱 이벤트를 사용하여 백그라운드 스레드를 만들 때 프론트 엔드 사용자 입력을 가질 수 없습니다.

아마도 당신이 성취하고자하는 것에 대한 큰 그림을 설명한다면, 우리는 더 잘 당신을 도울 수 있습니다.

그 동안 스레드 안전 쓰기를 작성하려고 할 수 있습니다. 이 article은 다른 스레드에서 양식 컨트롤에 쓰는 문제와 해결책을 이해하는 데 도움이됩니다.

+0

프로그램은 몇몇 인수를 취하는 프로세스이고, erro가 실행되고 닫히는 것이 selft라면 실행하려고하는 것은 프로세스를 실행하는 것이다. 프로세스가 작업으로 얼마나 오랫동안 완료되었는지 읽는 동안 작업을 수행하지 않는 것을 읽고 내 프로그램에 기록하십시오. >> 그 동안 Timer tick을 피하고 동일한 프로세스에서 읽음으로써 단일 스레드로 만들 수 있습니다. 내가 프로세스를 호출하는 함수를 읽어야한다는 뜻입니까? –

0

당신은 (예를 들어, new Process) 명시 적으로 프로세스 인스턴스를 생성하고 OutputDataReceived 이벤트, 그것을위한 CancelOutputRead() 완료 방법 BeginOutputReadLine() 등을 사용할 수있다.

이벤트 OutputDataReceived은 출력 데이터가 사용 가능한 즉시 다른 스레드에서 비동기 적으로 이라고합니다.

+0

나는 당신이 해결책을 시도했다. 문제의 업데이트로, 이제는 충돌이 일어나지 않는다. 또한 데이터를 전혀 얻지도 못했고, CancelOutputRead()를 어디에 둘지 알아낼 수도 없었다. –

0

'스레드 교차 예외'가 발생한다고 가정합니다. 다른 스레드에서 양식 컨트롤을 업데이트 한 다음 UI 스레드를 업데이트하기 때문에 발생할 수 있습니다.

+0

아니요, 오류 메시지가 없습니다. –