返回值的差异 返回语句和 Enviroment.ExitCode

本文关键字:Enviroment ExitCode 语句 返回 返回值 | 更新日期: 2023-09-27 17:55:28

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

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,
从禁用托管过程的视觉工作室,它是:10。

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

返回值的差异 返回语句和 Enviroment.ExitCode

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

vshost.exe进程使用 Assembly.ExecuteAssembly() 启动原始可执行文件,而 又被记录为"程序集入口点返回的值"。

但是,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

Environment.ExitCode的文档指出:

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

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

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

根据Microsoft:

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

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

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