(轉載)C# Process.Kill() 拒絕訪問(Access Denied) 的解決方案

需求:不少時候咱們須要後臺運行幾個Console來不停的計算數據,那麼部署到客戶服務器後,若是出現突發異常,程序掛掉了,那。。。?web

 
 
 
解決方案:封裝了一個對後臺運行程序不停監測的功能,若是發現程序有異常,可是進程還在,這個時候就Kill掉這個進程,重啓後臺計算程序,這裏的計算程序均爲"控制檯運行程序"。
 
 
 
代碼以下:
 
 
   if (進程是否掛掉)
                {
                    // 獲取全部進程
                    Process[] ps = Process.GetProcesses();
                    for (int i = 0; i < ps.Length; i++)
                    {
                        if (ps[i].ProcessName.StartsWith(「ProcessName"))
                        {
                            // 統計崩潰計數
                            CrashCount(obj.Name);
                            ps[i].Kill();
                        }
                    }
                    Process.Start(Path);
                    Console.WriteLine(ProcessName + "程序已重啓!");
                }
 
 
 
 
 
 
 
異常中能夠看到,Kill()進程的時候出現"拒絕訪問",在網上搜了下,解決方案大體就這幾種:
 
在config裏增長identity
<system.web>
  <identity impersonate="true" userName="Administrator" password="123456" />
</system.web> 
檢測程序用"管理員身份運行"
對監測的程序目錄分配權限
結果是這幾種方式都沒能解決此問題。
 
 
 
我查看了Kill()方法的註釋:
 
 
 //
        // 摘要: 
        //     當即中止關聯的進程。
        //
        // 異常: 
        //   System.ComponentModel.Win32Exception:
        //     未能終止關聯的進程。 - 或 - 正在終止該進程。 - 或 - 關聯的進程是一個 Win16 可執行文件。
        //
        //   System.NotSupportedException:
        //     您正嘗試爲遠程計算機上運行的進程調用 System.Diagnostics.Process.Kill()。 該方法僅對在本地計算機上運行的進程可用。
        //
        //   System.InvalidOperationException:
        //     該進程已經退出。 - 或 - 沒有與此 System.Diagnostics.Process 對象關聯的進程。
        public void Kill();
 
發現是一個Win32Exception的異常,隨後我又查閱了ms的官方文檔,果真有發現:
 
大概意思就是說若是這個監測程序是Console,這樣寫是沒問題的,能夠正常結束掉進程。但這裏由於須要在界面上展示出一些監測數據,這裏我用的是 WPF,也就是文檔裏說的圖像界面程序。
 
MS的原話是這樣的:若是調用 Kill,則可能丟失進程編輯的數據或分配給進程的資源。Kill 致使進程不正常終止,於是只應在必要時使用。CloseMainWindow 使進程可以有序終止並關閉全部窗口,因此對於有界面的應用程序,使用它更好。若是 CloseMainWindow 失敗,則可使用 Kill終止進程。Kill 是終止沒有圖形化界面的進程的惟一方法。
 
將Kill方法()改爲了CloseMainWindow()便可正常殺掉進程。
 
以上就是這兩天碰到的一個異常,讓我總結出了一個新的結論,在遇到問題的時候,不要盲目的去google或百度,應該首先去查閱ms的官方文檔。
相關文章
相關標籤/搜索