2014-12-05 2 views
0

내가 BackgroundWorkerWinForm (.NET 4.5 C#) 응용 프로그램을 가지고 있는데이 코드에서 다음 코드를 사용하여 새 을 시작합니다.System.Diagnostics.Process.Kill이 제대로 작동하지 않습니다. C#

void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker bw = sender as BackgroundWorker; 

     string fileName_ = e.Argument.ToString(); 

     Process myProcess = new Process(); 
     int exitCode = 0; 

     try 
     { 
      if (!File.Exists(fileName_)) 
      { 
       throw new FileNotFoundException("Failed to locate " + fileName_); 

      } 


      #region Start Info: 
      ProcessStartInfo startInfo = new ProcessStartInfo(fileName_); 
      startInfo.UseShellExecute = false; 
      startInfo.CreateNoWindow = true; 
      startInfo.RedirectStandardOutput = true; 
      startInfo.RedirectStandardError = true; 

      myProcess.StartInfo = startInfo; 
      #endregion 

      myProcess.Start(); 
      StreamReader myStreamReader = myProcess.StandardOutput; 

      while (!myProcess.HasExited) 
      { 
       myProcess.Refresh(); 
       string output = myStreamReader.ReadLine(); 
       bw.ReportProgress(0, output); 

       if (bw.CancellationPending) 
       { 
        myStreamReader.ReadToEnd(); 
        myStreamReader.Close(); 

        myProcess.StandardError.ReadToEnd(); 
        myProcess.StandardError.Close(); 
        myProcess.Kill(); 
        break; 

       } 

      } 


      //myProcess.WaitForExit(); 


      bw.ReportProgress(0, string.Format("Process {0} exit code: {1}", fileName_, myProcess.ExitCode)); 

      exitCode = myProcess.ExitCode; 
      if (exitCode != 0 && !bw.CancellationPending) 
      { 
       string error = myProcess.StandardError.ReadToEnd(); 


       myProcess.Close(); 
       myProcess = null; 

       bw.ReportProgress(0, "Process Failed with message:" + Environment.NewLine + error); 
      } 

      myProcess.Close(); 

     } 
     catch (Exception ex) 
     {     

      Console.WriteLine(ex); 

     } 
     finally 
     { 
      myProcess.Dispose(); 
      myProcess = null; 

     } 

     e.Result = exitCode; 
    } 

이 부분은 정상적으로 작동하지만 한번 사용해 보겠습니다. myProcess.Kill(); 백그라운드 작업자가 멈추고 모든 것은 정상이지만, 프로세스를 실행 중임을 여전히 볼 수있는 응용 프로그램을 닫더라도 작업 관리자에서 프로세스가 실행 중임을 알 수 있습니다.

제 질문은 올바르게 프로세스를 종료하는 방법입니다.

더 많은 정보가 필요하면 알려 주시기 바랍니다.

도움을 주시면 감사하겠습니다.

// -------------- 2014 년 12 월 8 일 업데이트 --------------------- //

@RogerN Process.WaitForExit()을 제거하고 응용 프로그램을 닫은 후에도 myStreamReader.ReadToEnd()와 동일한 문제가 계속 발생했습니다.

@phillip 이것은 WinForm에서 호출하는 콘솔 응용 프로그램 (독립 실행 형 * .exe)입니다.

@Peter Duniho 예 저는 그것이 작업 관리자에서 동일한 프로세스라고 확신합니다. WaitForExit()을 제거해도 아무 것도 해결하지 못했지만 BW는 실제로 문제없이 정상적으로 완료되었습니다.

@ L.B 어떤 대안을 제안합니까?

+0

어떤 유형의 프로세스입니까? 그것은 서비스가 있다면 당신은 독립 실행 형 exe 인 경우보다 다른 대답. – phillip

+1

작업 관리자에 표시되는 프로세스가 시작한 프로세스입니까? BW 코드는 시작한 프로세스에서 WaitForExit()을 호출하지만 실제로 BW가 실제로 완료되었다고 주장합니다. 그래서 코드에 약간의 모순이 있습니다. –

+0

관리자 권한으로 프로그램을 실행하고 있습니까? –

답변

3

전체 출력 스트림을 읽기 전에 Process.WaitForExit()을 호출하므로 교착 상태가 발생할 수 있습니다. 출력 스트림을 리디렉션했기 때문에 프로세스가 정상적으로 종료되기 전에 연결된 스트림의 모든 데이터를 읽어야합니다.

+0

이것은 일반적인 콘솔 실행 파일이며 Process.WaitForExit()은 여전히 ​​동일한 문제를 제거했습니다. 예, 작업 관리자의 프로세스가 동일하다고 확신합니다. 관리자 및 일반 사용자가 동일한 문제로 실행하려고했습니다. while 루프 대신에 무엇을 사용 하시겠습니까? – Farukh

+0

표준 출력과 표준 오류 스트림을 모두 리디렉션하므로 프로세스를 종료하기 전에 두 스트림의 끝까지 읽어야합니다. 위의 while 루프에서는 표준 오류 스트림이 아닌 표준 출력 만 읽으므로 프로세스가 정상적으로 종료되지 않을 수 있습니다. – RogerN

+0

루프를 업데이트 한 후 (내 첫 번째 게시물의 코드 참조) 응용 프로그램을 닫은 후에도 같은 문제가 발생했습니다. 뭔가 다른 것이 있어야합니다. ProcessStartInfo를 잘못 설정했을 수 있습니까? – Farukh