为了账号安全,请及时绑定邮箱和手机立即绑定

一个可执行文件可以既是控制台又是GUI应用程序?

一个可执行文件可以既是控制台又是GUI应用程序?

C#
LEATH 2019-09-21 11:02:40
我想制作一个可以作为CLI或GUI应用程序运行的C#程序,具体取决于传递给它的标志是什么。能做到吗?
查看完整描述

3 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

指向Raymond Chen的博客,该博客解释了为什么不能同时拥有控制台程序和非控制台*程序的应用程序:操作系统需要在程序开始运行要使用的子系统之前就知道。程序开始运行后,现在返回并请求其他模式为时已晚。


Cade的答案指向有关使用控制台运行.Net WinForms应用程序的文章。它使用AttachConsole程序开始运行后调用的技术。这样的效果是允许程序将其写回到启动程序的命令提示符的控制台窗口。但是该文章中的评论指出了我认为是致命的缺陷:子进程实际上并不控制控制台。控制台继续代表父进程接受输入,并且父进程不知道在将控制台用于其他用途之前,它应等待子进程完成运行。


Chen的文章指向Zhang Junfeng Zhang的文章,它解释了其他两种技术。


首先是devenv的用途。它实际上有两个程序。一个是主界面GUI程序devenv.exe,另一个是处理控制台模式任务的devenv.com,但是如果以非控制台方式使用它,则它将其任务转发给devenv.exe和退出。该技术依赖于Win32规则,当您键入不带文件扩展名的命令时,将在exe文件之前选择com文件。


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


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


该程序被标记为控制台模式二进制文件,因此它始终从控制台开始。这样可以使输入和输出重定向正常进行。

如果程序没有控制台模式命令行参数,它将重新启动自身。

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


因此,第一个实例会自行重启(我想带有一个额外的命令行参数)。当您调用时CreateProcess,有两个不同的标志可以尝试使用,分别是DETACHED_PROCESS和CREATE_NEW_CONSOLE,这两个标志将确保第二个实例不会附加到父控制台。此后,第一个实例可以终止并允许命令提示符恢复处理命令。


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


我认为,Junfeng文章中有关使用editbin更改程序的控制台模式标志的部分是一个红色的鲱鱼。您的编译器或开发环境应提供一个设置或选项来控制它创建哪种二进制文件。此后无需再进行任何修改。


最重要的是,您可以具有两个二进制文件,也可以具有控制台窗口的瞬时闪烁。一旦确定哪个是较小的邪恶,就可以选择实现。


*我说的是非控制台而不是GUI,因为这是错误的二分法。仅仅因为程序没有控制台并不意味着它具有GUI。服务应用程序就是一个很好的例子。另外,程序可以具有控制台和窗口。


查看完整回答
反对 回复 2019-09-21
  • 3 回答
  • 0 关注
  • 534 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信