I am writing a console program for windows task scheduler to run. My Main()
method has a return type of int
and I return different numbers when exiting to indicate the result of execution, which I can access in a .BAT
script as %errorlevel%
.
However when debugging in VS2015, I do a
return 255;
and I always get from the Output window of VS2015:
The program '[43560] Foo.vshost.exe' has exited with code 0 (0x0).
Now if I want the Output window to display the exit code of my program I have to do a Application.Exit(255)
for it to show
The program '[24400] Foo.vshost.exe' has exited with code 255 (0xff).
What's strange is the %errorlevel%
is correctly set to 255 if I run the program in CMD.exe
with either the return statement or Environment.Exit()
.
So my question is
Is the return value of Main()
somewhat different to Environment.ExitCode
?
What is the way to easily find out the return value of Main()
method in VS2015?
When exiting a console program, is Environment.Exit()
preferred than a simple return statement? Because a return statement is more concise to my taste.
Could somebody tell me the story behind this? Thanks.
Is the return value of Main() somewhat different to Environment.ExitCode?
Nope, they are the same, and go to the same place. You can see this by experimenting with a console application that just either returns -1 or sets Environment.ExitCode
to -1. You'll see that whichever method you use works and sets %ERRORLEVEL%
correctly.
What is the way to easily find out the return value of Main() method in VS2015?
First, a quick aside about what appears to be happening. Here's the stack trace for a console application created using the default project settings:
TestApp.exe!TestApp.Program.Main(string[] args)
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args)
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()
Notice that the VS host process is there. With the VS hosting process disabled the stack trace (with the same options) looks like this:
TestApp.exe!TestApp.Program.Main(string[] args)
If you look at the definition of ThreadHelper.ThreadStart
in the reference source you'll see it defined as:
internal void ThreadStart(object obj)
It seems that either this void return is being used as the process return value, or one of the other methods above it is consuming the return value and swallowing it.
If you change the project configuration and disable the hosting process then you will get output like:
The program '[7992] TestApp.exe' has exited with code -1 (0xffffffff).
As you expect. To disable the hosting process, go to the project properties, and on the debug tab, uncheck the "Enable the Visual Studio hosting process"
When exiting a console program, is Environment.Exit() preferred than a simple return statement? Because a return statement is more concise to my taste.
Whichever you prefer. As pointed out by Jeppe Stig in a comment, for more information about the differences, see the documentation for Environment.Exit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With