2015-09-12 45 views
13

如果.net程序在終止之前未明確設置退出代碼(通過調用Environment.Exit()/Appliation.Current.Shutdown()/...),那麼該過程的退出代碼是什麼?當沒有使用Environment.Exit()時,.NET程序可以使用哪些退出代碼?

正常終止是否總是導致退出代碼爲零,以及其他可能的情況是什麼?

根據this answer到由Hans帕桑特的相關問題Getting ExitCode From Exception Handler:「如果程序上的異常晶粒然後退出代碼通常相同底層異常錯誤代碼」。

因此,一個uncaugth異常可以退出代碼。這是總是的情況下,並且是基本的異常錯誤代碼總是保證是不同於零,並在一個特定的範圍?

是否有其他地方的情況在.NET Framework或Windows可以自動設置另一個退出代碼,比如一些非異常相關的崩潰(這可能嗎?),或強制任務殺?

換一種說法,我可以通過退出代碼來確定程序是否以任何異常方式終止?
或者如果在某些異常情況下退出代碼也可能發生,我可否在程序的所有正常終止路徑中包含Environment.Exit(somevalue),並確保在出現崩潰時不會出現此退出代碼?


動機:
由於not all exeptions are catchable沒有嚴重的變通方法,並且因爲可能有其他原因比未捕獲excpetions其他突發程序終止,確保所有的代碼路徑調用Environment.Exit()不是alwas可能。這就是爲什麼我有興趣確定是否可以使用退出代碼來可靠地確定程序是否正常退出。

+0

我在我的問題和建議的重複之間添加了差異。雖然第二個答案也有助於我的問題的一部分,但它沒有完全回答它,而問題本身則完全不同。 – HugoRune

+0

Tangental建議:啓用Windows錯誤報告,並創建啓用小型轉儲的選項。這樣你不僅有一個退出代碼,而且還可以通過調試器傳遞異常記錄和部分堆棧。 (就像使用SOS調試器的WinDBG一樣。)即使沒有小型轉儲程序,WER也會捕獲有關錯誤消息本身的一些信息。對於內部應用程序,您甚至可以設置服務器以便自動提交崩潰報告。 TechNet上的此[頁面](https://technet.microsoft.com/en-us/library/cc709644.aspx)有一個很好的概述。 – theB

+0

退出代碼是相當無用的恕我直言。更多在這裏:http://stackoverflow.com/questions/4344923/process-exit-code-when-process-is-killed-forcibly –

回答

5

然後退出代碼通常一樣的底層異常錯誤代碼

6個月後,你應該已經建立了一定的信心是正常適用。可能工作得很好,你不能在這裏得到保證。不僅僅是未處理的異常會使進程終止,並且您永遠無法確定它始終是當進程死於異常時運行的相同代碼。

有太多的東西想要參與這個,它並不總是最好的質量。在列表之上肯定是反惡意軟件,那裏有很多cr * pware,你永遠不會知道你遇到了什麼。最近的Avast災難給了很多理由關注這個。幾乎沒有結束的地方,代替WER的公用設施已經足夠普及了。

你是針對認爲了TerminateProcess()是解決文件鎖定問題的好辦法粗人完全不設防。或有人絆倒電源線並拔下電源插頭。爲什麼你想知道的退出代碼

關注一點。應該有下一步使用程序結果繼續執行的內容。驗證結果。

2

你正在執行你自己的過程嗎?也就是說,你可以在可預測的情況下控制退出代碼嗎? 如果是這樣,你可以捕獲拋出的異常,然後返回自己的可預測的非零異常代碼(一個特定的值或你自己的範圍)。由於系統錯誤代碼是肯定的,我會使用負數。 這樣,你有三種可能性:

  1. 零 - 成功
  2. 負 - 過程扔,你是能夠趕上
  3. 正異常 - 過程扔,你不能捕捉異常。那將是異常的。

除此之外的任何東西似乎都不可預測。如果遠遠超出正常範圍,甚至進程甚至不能返回非零退出代碼,那麼等待該退出代碼的進程也可能失敗。檢查一個非零的退出代碼是您可以合理地做的以解決由於任何不可預見的原因導致失敗的可能性。

我不知道#3是否有可能,但是如果你想要解釋未知,那麼這可能是你能做的最多的事。

下面是一個例子:

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     var exitCode = 0; 
     try 
     { 
      //do something 
     } 
     catch (SystemException systemEx) 
     { 
      //log 
      exitCode = -systemEx.HResult; 
     } 
     catch (Exception ex) 
     { 
      //log 
      Environment.ExitCode = int.MinValue; 

     } 
     Environment.ExitCode = exitCode; 
    } 
} 

這就是你可以做什麼。但我不會使用退出碼來描述錯誤。我會使用日誌記錄。我會使用退出代碼告訴調用應用程序要做什麼。零或非零可能就足夠了。我寫了更復雜的返回代碼,指出失敗是IO相關的還是SQL相關的,最後我從來沒有使用過它。如果失敗,我會查看我的日誌中是否有錯誤消息。

相關問題