【问题标题】:Difference in returning value by return statement and Enviroment.ExitCodereturn 语句和 Enviroment.ExitCode 的返回值差异
【发布时间】:2015-06-11 20:18:11
【问题描述】:

我正在玩控制台的返回值,我看到了一些有趣的东西。有什么区别:

static void Main(string[] args)
{
    Environment.ExitCode = 4;
}

static int Main(string[] args)
{
    return 10;
}

?

如果我同时使用:

static int Main(string[] args)
{
    Environment.ExitCode = 4;
    return 10;
}

然后退出代码:
在命令行中总是:10,
在视觉工作室中是:4,
来自具有禁用托管进程的 Visual Studio,它是:10.

问题:
这两种设置退出代码的方法有什么不同?哪一种被认为是最适合使用的?

【问题讨论】:

  • 来自 msdn,Environment.ExitCode 在第三个示例中应该被忽略,因为您有一个非void Main。所以是vshost的问题。

标签: c#


【解决方案1】:

响应“vshost.exe”在这种情况下产生的差异。

vshost.exe 进程使用Assembly.ExecuteAssembly() 启动原始可执行文件,而documented 又是“程序集入口点返回的值”。

但是,vshost.exe 可执行文件的(生成的)Main 方法不返回 int,而是返回 void。也就是说,它忽略了ExecuteAssembly返回的值。

例如,它看起来不像这样/概念上:

  class VsHost
  {
      public static int Main(string[] args) {
           // ...
           return appDomain.ExecuteAssembly("true.exe", ...);
      }
  }

而是看起来像这样:

  class VsHost
  {
      public static void Main(string[] args) {
           // ...
           appDomain.ExecuteAssembly("true.exe", ...);
           // Nothing here...
      }
  }

因此,基本上,当它退出时,唯一设置的退出代码是Environment.ExitCode 在“真实”可执行文件中提供的退出代码。请注意,ExitCode 是全局值,与设置它的 AppDomain 无关。

您可以使用第三个示例和以下“vshost-mock”轻松测试此行为:

   // Compile to "Example3.exe"
   using System;
   class Example3
   {
       public static int Main(string[] args) {
           Environment.ExitCode = 4;
           return 5;
       }
   }

   // Complile to "VsHostMock.exe"
   using System;
   class VsHostMock
   {
       public static void Main(string[] args) {
          var appDomain = AppDomain.CreateDomain("other");
          int returnCode = appDomain.ExecuteAssembly("Example3.exe");
          Console.WriteLine("ReturnCode: {0}", returnCode);
          Console.WriteLine("Environment.ExitCode: {0}", Environment.ExitCode);
       }
   }

然后运行以下命令:

   C:\> VsHostMock.exe ; echo %ERRORLEVEL%
   ReturnCode: 5
   Environment.ExitCode: 4

然后运行:

   C:\> echo %ERRORLEVEL%
   4

【讨论】:

    【解决方案2】:

    Environment.ExitCode 的文档指出:

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

    因此,在您的情况下,您的 main 返回一个 int,这意味着不应真正使用 Environment.ExitCode(文档指出它显然会被忽略)。如果您的main 返回void,那么Environment.ExitCode 的行为似乎与预期一样。

    当您将Environment.ExitCodeint main() 方法一起使用时,当您使用调试器运行时可能会抛出奇怪的结果?

    【讨论】:

      【解决方案3】:

      根据微软:

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

      参考https://msdn.microsoft.com/en-us/library/system.environment.exitcode%28v=vs.110%29.aspx

      我个人更喜欢使用Main 中的return,但我想像往常一样,选择完全取决于你。

      【讨论】:

        猜你喜欢
        • 2021-02-06
        • 1970-01-01
        • 1970-01-01
        • 2022-12-09
        • 2020-12-03
        • 2021-11-22
        • 2012-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多