首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一个可执行文件可以同时作为控制台和GUI应用程序吗?

一个可执行文件可以同时作为控制台和GUI应用程序吗?
EN

Stack Overflow用户
提问于 2009-01-29 21:32:08
回答 9查看 45.5K关注 0票数 88

我想制作一个C#程序,它可以作为命令行界面或图形用户界面应用程序运行,这取决于传递给它的标志。这可以做到吗?

我已经找到了这些相关的问题,但它们并不完全涵盖我的情况:

EN

Stack Overflow用户

回答已采纳

发布于 2009-01-29 23:54:32

Jdigital's answer指出了Raymond Chen's blog,它解释了为什么不能同时拥有既是控制台程序又是非控制台*程序的应用程序:在程序开始运行之前,操作系统需要知道要使用哪个子系统。一旦程序开始运行,就来不及返回并请求另一种模式。

Cade's answer指向了an article about running a .Net WinForms application with a console。它使用在程序开始运行后调用AttachConsole的技术。这样做的效果是允许程序写回启动程序的命令提示符的控制台窗口。但那篇文章中的评论指出了我认为是一个致命的缺陷:子进程并不真正控制控制台。控制台继续代表父进程接受输入,并且父进程不知道在使用控制台进行其他操作之前,它应该等待子进程完成运行。

陈的文章指向了an article by Junfeng Zhang that explains a couple of other techniques

第一个是devenv使用的。它的工作原理实际上是有两个程序。一个是devenv.exe,它是主图形用户界面程序,另一个是devenv.com,它处理控制台模式的任务,但是如果以非控制台的方式使用它,它会将其任务转发给devenv.exe并退出。该技术依赖于Win32规则,即当您键入不带文件扩展名的命令时,会优先选择com文件而不是exe文件。

Windows脚本宿主在这方面有一个更简单的变体。它提供了两个完全独立的二进制文件: wscript.exe和cscript.exe。同样,Java为控制台程序提供java.exe,为非控制台程序提供javaw.exe。

俊峰的第二种技术是ildasm使用的。他引用了ildasm的作者在两种模式下运行时所经历的过程。归根结底,它的作用如下:

  1. 该程序被标记为控制台模式二进制文件,因此它始终从控制台开始。这允许输入和输出重定向正常工作。
  2. 如果程序没有控制台模式命令行参数,它将重新启动自身。

仅仅调用FreeConsole来使第一个实例不再是控制台程序是不够的。这是因为启动该程序的进程cmd.exe“知道”它启动了一个控制台模式的程序,并且正在等待该程序停止运行。调用FreeConsole会使ildasm停止使用控制台,但不会使父进程开始使用控制台。

因此,第一个实例会自动重新启动(我想是通过一个额外的命令行参数)。当您调用CreateProcess时,有两个不同的标志可供尝试,DETACHED_PROCESS and CREATE_NEW_CONSOLE,这两个标志中的任何一个都将确保第二个实例不会附加到父控制台。之后,第一个实例可以终止并允许命令提示符继续处理命令。

这种技术的副作用是,当您从GUI界面启动程序时,仍然会有一个控制台。它会在屏幕上瞬间闪现,然后消失。

在俊峰的文章中,关于使用editbin来改变程序的控制台模式标志的部分,我认为是在转移注意力。您的编译器或开发环境应该提供一个设置或选项来控制它创建的二进制文件的类型。之后应该不需要修改任何东西。

因此,底线是,您可以拥有两个二进制文件,也可以拥有控制台窗口的瞬间闪烁。一旦你决定了哪一个是较小的邪恶,你可以选择你的实现。

*我说的是非控制台,而不是图形用户界面,否则这是错误的二分法。一个程序没有控制台并不意味着它有GUI。服务应用程序就是一个很好的例子。此外,一个程序可以有一个控制台和窗口。

票数 108
EN
查看全部 9 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/493536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档