senfen
senfen

Reputation: 907

Difference in returning value by return statement and Enviroment.ExitCode

I'm playing with return value from console and I saw some interesting. What differences came from:

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

and

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

?

If I use both:

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

Then exit code:
in commandline it is always: 10,
in visual studio it is: 4,
from visual studio with disabled hosting process it is: 10.

Question:
What differs this two methods of setting exit code and which one is considered as most proffered to use?

Upvotes: 2

Views: 275

Answers (3)

Christian.K
Christian.K

Reputation: 49250

In response to the difference that "vshost.exe" makes in this scenario.

The vshost.exe processes launches the original executable using Assembly.ExecuteAssembly(), which in turn is documented to "The value returned by the entry point of the assembly."

However, the (generated) Main-method of vshost.exe executables doesn't return int, but void. That is, it ignores the value returned by ExecuteAssembly.

For example, it does not look something/conceptually like this:

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

But rather looks something like this:

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

So, basically, when it exits, the only exit code that is set, is the one provided by Environment.ExitCode in the "real" executable. Mind you, that the ExitCode is global value, independent of the AppDomain it was set in.

You can easily test this behavior using your third example and the following "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);
       }
   }

Then run the following:

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

Then run:

   C:\> echo %ERRORLEVEL%
   4

Upvotes: 2

Martin
Martin

Reputation: 16423

According to Microsoft:

If the Main method returns void, you can use this property to set the exit code that will be returned to the calling environment. If Main does not return void, this property is ignored. The initial value of this property is zero.

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

I personally prefer to use return from Main, but I guess as usual the choice would be entirely down to you.

Upvotes: 0

Jason Evans
Jason Evans

Reputation: 29186

The documentation for Environment.ExitCode states:

If the Main method returns void, you can use this property to set the exit code that will be returned to the calling environment. If Main does not return void, this property is ignored. The initial value of this property is zero.

So in your case, your main returns an int which means that Environment.ExitCode should not be used really (the documentation states it will be ignored apparently). If your main was returning void than it seems that Environment.ExitCode would behave as expected.

As you are using Environment.ExitCode with an int main() method, that might be throwing up weird results when you run with a debugger?

Upvotes: 1

Related Questions