【问题标题】:How do I specify the exit code of a console application in .NET?如何在 .NET 中指定控制台应用程序的退出代码?
【发布时间】:2010-09-14 09:53:39
【问题描述】:

我在 .NET 中有一个简单的控制台应用程序。它只是一个更大的应用程序的一个测试部分。我想指定我的控制台应用程序的“退出代码”。我该怎么做?

【问题讨论】:

    标签: c# .net exit-code


    【解决方案1】:
    int code = 2;
    Environment.Exit( code );
    

    【讨论】:

    • 任何技术原因你不只是写“Environment.Exit(2);” ?
    • 将一个幻数分配给一个名称无意义的变量并不会降低它的魔力。
    【解决方案2】:
    【解决方案3】:

    只需从 main 返回适当的代码。

    int Main(string[] args)
    {
          return 0; //or exit code of your choice
    }
    

    【讨论】:

      【解决方案4】:

      3 个选项:

      • 如果你声明你的Main方法返回int,你可以从Main返回它。
      • 您可以拨打Environment.Exit(code)
      • 您可以使用属性设置exit codeEnvironment.ExitCode = -1;。如果没有其他设置返回代码或使用上述其他选项之一,则将使用此选项)。

      根据您的应用程序(控制台、服务、Web 应用程序等),可以使用不同的方法。

      【讨论】:

      • 对于那些想知道为什么这在他们的情况下不起作用的人,请确保您的项目被编译为“控制台应用程序”而不是“Windows 应用程序”。
      • 如果我有一个带有一些参数的 WinForms 应用程序,我希望它像控制台应用程序一样运行怎么办?
      • 您也可以将 maine 程序键入为 int(将 void 替换为 int)并使用例如“返回-1;”从主程序返回。这比 Environment.Exit() 更便携(取决于环境)。
      • @DannyBeckett 按照惯例,退出代码0 表示成功,非零表示失败。 return; 通过退出代码0 表示成功,return -1; 表示失败。
      • 您也可以使用属性设置退出代码:Environment.ExitCode = -1;
      【解决方案5】:

      如果您的 main 有一个无效的返回签名,请使用 ExitCode,否则您需要通过您返回的值“设置”它。

      Environment.ExitCode Property

      如果 Main 方法返回 void,您可以使用此属性设置将返回给调用环境的退出代码。如果 Main 不返回 void,则忽略此属性。此属性的初始值为零。

      【讨论】:

        【解决方案6】:

        除了涵盖 return int 的答案之外......呼吁理智。请在枚举中定义您的退出代码,如果合适,请使用标志。它使调试和维护变得如此容易(而且,作为奖励,您可以轻松地在帮助屏幕上打印出退出代码 - 您确实拥有其中一个,对吧?)。

        enum ExitCode : int {
          Success = 0,
          InvalidLogin = 1,
          InvalidFilename = 2,
          UnknownError = 10
        }
        
        int Main(string[] args) {
           return (int)ExitCode.Success;
        }
        

        【讨论】:

        • 您可能想补充一点,“成功”的“0”值不是偶然的,而是该情况的“标准”值。
        • 我知道 0 是成功的标准。其他退出代码是否有商定的约定,还是只是对所有人免费? (我认为这些数字与您在运行计划任务后返回的数字相同)。
        • 你说 0 是成功的标准值,但是在将 0/1 转换为布尔值时,0 为假,1 为真!更准确地说,退出代码 0 表示“没有错误”而不是“成功”,因为退出代码是 ErrorResult 而不仅仅是 Result。
        • 有关微软约定的完整列表,请参阅msdn.microsoft.com/en-us/library/windows/desktop/…。有人制作了一个庞大的 const 列表,并将其用于下面 cmets 的 switch case。
        • @MarkShapiro,我猜0 = Success 来自这样一个事实,即只需要一个成功代码,但是许多错误代码,例如 0,在计算机整数中没有 + 或 - 可以是用于唯一标识成功
        【解决方案7】:

        枚举选项非常好,但是可以通过将数字相乘来改进,如下所示:

        enum ExitCodes : int
        {
          Success = 0,
          SignToolNotInPath = 1,
          AssemblyDirectoryBad = 2,
          PFXFilePathBad = 4,
          PasswordMissing = 8,
          SignFailed = 16,
          UnknownError = 32
        }
        

        在出现多个错误的情况下,将特定错误编号相加将为您提供一个唯一编号,该编号代表检测到的错误的组合。

        例如,errorlevel 6 只能由error 4 和2 组成,12 只能由error 4 和8 组成,14 只能由2、4 和8 组成等等。

        【讨论】:

        • 不过,如果您在遇到错误后还要检查是否有其他错误。大多数应用都没有。
        【解决方案8】:

        如果你打算使用 David 建议的方法,你还应该看看 [Flags] 属性。

        这允许您对枚举执行按位操作。

        [Flags]
        enum ExitCodes : int
        {
          Success = 0,
          SignToolNotInPath = 1,
          AssemblyDirectoryBad = 2,
          PFXFilePathBad = 4,
          PasswordMissing = 8,
          SignFailed = 16,
          UnknownError = 32
        }
        

        然后

        (ExitCodes.SignFailed | ExitCodes.UnknownError)
        

        应该是 16 + 32。:)

        【讨论】:

        • 这意味着程序会说“您的密码错误”然后继续尝试签署它正在签署的任何内容,并且只有在失败时才停止。一旦失败,您应该返回;其他任何内容都是警告,程序仍应返回 0。
        • 鲜为人知的事实是 [Flags] 对启用或禁用按位运算没有任何作用。它所做的只是覆盖 ToString 方法,以便输出表示按位标志。不管有没有它,你仍然可以进行按位运算。
        • @Steven 很高兴知道,但我仍然建议使用该属性装饰用于“标志使用”的枚举,如果没有其他传达意图的话。
        【解决方案9】:

        您可以使用三种方法从控制台应用程序返回退出代码。

        1. 修改应用程序中的Main 方法,使其返回int 而不是void(该函数在VB.Net 中返回Integer 而不是Sub),然后返回退出代码从那个方法。
        2. Environment.ExitCode 属性设置为退出代码。请注意,方法 1. 优先 - 如果 Main 方法返回 void 以外的任何值(在 VB.Net 中是 Sub),则此属性的值将被忽略。
        3. 将退出代码传递给Environment.Exit 方法。与其他两种方法不同,这将立即终止进程。

        应遵守的一个重要标准是0 代表“成功”。

        在相关主题中,考虑使用枚举来定义您的应用程序将要返回的退出代码。 FlagsAttribute 将允许您返回代码组合。

        另外,请确保您的应用程序被编译为“控制台应用程序”。

        【讨论】:

        • 这带来了一个有趣的观点。设置Environment.ExitCode 不会立即关闭程序,但Environment.Exit 方法会立即关闭程序
        • 退出代码也适用于 Windows 应用程序。如果应用程序将从c#启动,通过Process对象,您可以向WaitForExit()请求对象,然后向它请求退出代码。
        【解决方案10】:

        我的 2 美分:

        您可以在此处找到系统错误代码: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

        您会发现典型的代码,例如“找不到文件”的 2 或“拒绝访问”的 5。

        当你偶然发现一个未知代码时,你可以使用这个命令来找出它的含义:

        net helpmsg decimal_code
        

        例如

        net helpmsg 1

        返回

        函数不正确

        【讨论】:

          【解决方案11】:

          作为 Scott Munro 的 answer 的更新:

          • 在 C# 6.0 和 VB.NET 14.0 (VS 2015) 中,需要 Environment.ExitCodeEnvironment.Exit(exitCode) 从控制台应用程序返回非零代码。更改 Main 的返回类型无效。
          • 在 F# 4.0 (VS 2015) 中,main 入口点的返回值受到尊重。

          【讨论】:

          • 可以验证您关于 C# 6 的第一点吗?我似乎在网上找不到任何东西。 Main 函数的返回值附加到进程的退出代码(至少在所有以前的编译器中),为什么他们应该更改它?
          • 纯轶事证据,但我只是在我自己的库中遇到了这个问题,只是从Main() 返回我的结果/错误代码并没有设置调用应用程序所看到的Process.ExitCode
          • MSDN 认为 int Main 仍然可以用作 Environment.ExitCode 的替代品。 link
          • 我有一个运行多个线程的应用程序。在某些情况下,我需要在退出应用程序之前通过 Thread.Abort() 破坏一些线程。在这些情况下, int Main(){...thread.Abort(); ... return 0;} 不会导致进程退出代码为 0:进程退出代码为 -1。似乎在某些情况下,MS 已经决定使用主线程的返回值来设置进程的退出代码的约定对他们来说还不够好。公平地说,这可能是一个时间问题:线程中止可能会在游戏中很晚才设置退出代码。
          【解决方案12】:

          使用此代码

          Environment.Exit(0);
          

          如果您不想返回任何内容,请使用 0 作为 int。

          【讨论】:

          • 这不是回答 OP 的问题,返回 0 就是返回一些东西......
          • 它返回的是应用程序通常返回的内容。如果不指定,应用返回 0
          【解决方案13】:

          只是另一种方式:

          public static class ApplicationExitCodes
          {
              public static readonly int Failure = 1;
              public static readonly int Success = 0;
          }
          

          【讨论】:

            【解决方案14】:

            我就是这么干的

            int exitCode = 0;
            Enviroment.Exit(exitCode);
            

            或者你可以抛出错误(个人喜好)

            throw new ArgumentException("Code 0, Enviroment Exit");
            

            我选择了 ArgumentException,但您可以输入其他。它会正常工作的。

            【讨论】:

              猜你喜欢
              • 2016-08-29
              • 2010-11-10
              • 2016-12-08
              • 2020-01-30
              • 1970-01-01
              • 2014-02-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多