2014-12-05 60 views
0

我有WinForm (.NET 4.5 C#)應用程序,我有BackgroundWorker從哪裏我開始新Process使用下面的代碼。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 2014-12-05 20:23:42

+1

您確定您在任務管理器中看到的過程是您開始的過程嗎?您的BW代碼在它啓動的進程中調用'WaitForExit()',然後終止,但您聲稱BW確實完成了。所以在代碼和你說的發生了一些矛盾。 – 2014-12-05 20:28:08

+0

您是否以管理員身份運行程序? – 2014-12-05 20:28:13

回答

3

可能會因爲在讀取整個輸出流之前調用Process.WaitForExit()而發生死鎖。既然你已經重定向了輸出流,你必須在流程可以正常退出之前從關聯流中讀取所有數據。

+0

這是正常的控制檯可執行文件,我刪除了Process.WaitForExit()仍然是同樣的問題。是的,我相信這是我的任務管理器中的相同過程。 我試圖以管理員和普通用戶相同的問題運行。 你用什麼來代替while循環? – Farukh 2014-12-07 16:24:22

+0

由於您正在重定向標準輸出和標準錯誤流,因此您需要確保在流程退出之前您可以讀取兩個流的末尾。在上面的while循環中,您只能從標準輸出中讀取,而不是標準錯誤流,因此該過程可能永遠不會正常退出。 – RogerN 2014-12-09 18:34:13

+0

我更新while循環(請參閱我的第一篇文章中的代碼),同樣的問題過程在關閉應用程序後仍然存在。應該有其他的東西是錯的。也許我錯誤地設置了ProcessStartInfo? – Farukh 2014-12-09 20:07:01