2015-09-12 25 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相关的,最后我从来没有使用过它。如果失败,我会查看我的日志中是否有错误消息。

相关问题