【问题标题】:C# console application: Main method return value VS Application.ExitCodeC# 控制台应用程序:Main 方法返回值 VS Application.ExitCode
【发布时间】:2016-10-10 22:05:58
【问题描述】:

我正在编写一个控制台程序来运行 Windows 任务调度程序。我的Main() 方法的返回类型为int,我在退出时返回不同的数字以指示执行结果,我可以在.BAT 脚本中以%errorlevel% 访问。

但是在 VS2015 中调试时,我做了一个

return 255;

我总是从 VS2015 的输出窗口得到:

The program '[43560] Foo.vshost.exe' has exited with code 0 (0x0).

现在,如果我希望输出窗口显示我的程序的退出代码,我必须执行 Application.Exit(255) 才能显示

The program '[24400] Foo.vshost.exe' has exited with code 255 (0xff).

如果我在CMD.exe 中使用return 语句或Environment.Exit() 运行程序,那么奇怪的是%errorlevel% 正确设置为255。

所以我的问题是

  1. Main() 的返回值与Environment.ExitCode 是否有些不同?

  2. 在VS2015中有什么方法可以轻松找出Main()方法的返回值?

  3. 退出控制台程序时,Environment.Exit() 是否比简单的 return 语句更受欢迎?因为返回语句更符合我的口味。

谁能告诉我这背后的故事?谢谢。

【问题讨论】:

    标签: c# return-value exit-code main-method


    【解决方案1】:

    Main() 的返回值与 Environment.ExitCode 是否有些不同?

    不,他们是一样的,去同一个地方。您可以通过尝试仅返回 -1 或将 Environment.ExitCode 设置为 -1 的控制台应用程序来看到这一点。您会看到无论您使用哪种方法都可以正常工作并正确设置 %ERRORLEVEL%

    VS2015有什么方法可以轻松找出Main()方法的返回值?

    首先,简要介绍一下正在发生的事情。以下是使用默认项目设置创建的控制台应用程序的堆栈跟踪:

    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()
    

    请注意,VS 主机进程在那里。禁用 VS 托管进程后,堆栈跟踪(使用相同的选项)如下所示:

    TestApp.exe!TestApp.Program.Main(string[] args)
    

    如果您查看reference sourceThreadHelper.ThreadStart 的定义,您会看到它定义为:

    internal void ThreadStart(object obj)
    

    似乎这个 void return 被用作进程返回值,或者上面的其他方法之一正在消耗返回值并吞下它。

    如果您更改项目配置并禁用托管过程,那么您将获得如下输出:

    The program '[7992] TestApp.exe' has exited with code -1 (0xffffffff).
    

    如您所愿。要禁用托管进程,请转到项目属性,然后在调试选项卡上,取消选中“启用 Visual Studio 托管进程”

    退出控制台程序时,Environment.Exit() 是否比简单的 return 语句更受欢迎?因为返回语句更符合我的口味。

    随你喜欢。正如 Jeppe Stig 在评论中指出的那样,有关差异的更多信息,请参阅Environment.Exit 的文档

    【讨论】:

    • 另请参阅the Environment.Exit(Int32) method documentation 了解差异列表。
    • @JeppeStigNielsen 好点。添加注释以防您的评论消失。
    • 首选从 main 返回退出。调用 Environment.Exit 是一种 hack,在设计良好的应用程序中应该没有必要。
    • 感谢大家提供 MSDN 链接并指出我将进一步探索的 Visual Studio 托管过程的正确方向。另外,在查看 MSDN 之后,我得出结论,return 语句似乎是退出应用程序的一种更优雅的方式。
    • 如果您不想使用Environment.Exit(errorCode),但无论如何要使用显示结果的托管进程,您可以在使用void Main( 签名的同时设置Environment.ExitCode 属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多