Windows 和控制台应用程序之间的区别
Posted
技术标签:
【中文标题】Windows 和控制台应用程序之间的区别【英文标题】:Difference between Windows and Console application 【发布时间】:2009-02-22 13:17:35 【问题描述】:Windows 和控制台应用程序有什么区别?
在 Visual C++ 中创建新项目时,它会要求选择上述任何一个。
【问题讨论】:
【参考方案1】:唯一的区别是,如果控制台应用程序不是从一个控制台启动(或者控制台在启动时被主动抑制),它总是会生成一个控制台。另一方面,Windows 应用程序不会产生控制台。它可以仍然附加到现有控制台或使用AllocConsole
创建一个新控制台。
这使得 Windows 应用程序更适合 GUI 应用程序或后台应用程序,因为您通常不希望为这些应用程序创建终端窗口。
从技术角度讲,控制台和 Windows 可执行文件之间的唯一区别是exe
文件的 PE 标头中的 一个字节。手动切换此字节(例如,使用十六进制编辑器)转换应用程序类型。这是一个广为人知的 hack,用于在 VB6 中创建控制台应用程序(未明确支持此类应用程序)。
要确定和更改应用程序的子系统类型,您需要读取部分 PE 标头。子系统数据的地址不是固定的,因为它是可选文件头的一部分,其位置由存储在 DOS 文件头中的地址确定(在成员 e_lfanew
中)。该地址实际上指向_IMAGE_NT_HEADERS
记录,该记录又包含IMAGE_OPTIONAL_HEADER32
结构。这有一个名为Subsystem
的int16
1) 成员。 Windows 应用程序的成员值为 2,控制台应用程序的成员值为 3。存在其他子系统(特别是 POSIX 和内核)。
我写了一个小的VB6应用程序来改变一个应用程序的子系统,可以从ActiveVB下载作为源代码。
PE 格式没有很好的文档记录,但此文档可以作为介绍:Peering Inside the PE: A Tour of the Win32 Portable Executable File Format。
1) 这与我声称只有一个字节不同的说法并不矛盾:该成员的最高有效字节始终为 0。只有最低有效字节发生变化。
【讨论】:
引用的DLL也没有区别吗? @SoapBox:查看更新后的答案。地址不是固定的,必须计算出来。我已经发布了一些 VB6 代码的链接来读取这些数据。 MSDN 文章还展示了如何执行此操作。 我父亲过去只是用自定义程序替换链接器,该程序更改了相应文件中的链接器命令行,然后在其上运行实际的链接器。最终结果与在可执行文件中切换字节相同,当然:)【参考方案2】:除了 Konrad 提到的差异之外,控制台和 Windows 应用程序在从命令提示符交互调用时表现不同:
当您启动控制台应用程序时,命令提示符在控制台应用程序退出之前不会返回。 当您启动 Windows 应用程序时,该命令会立即返回。
这不适用于批处理文件;他们将一直等到应用程序退出。 (您可以随时使用start
命令启动应用程序而无需等待。)
【讨论】:
【参考方案3】:区别在于应用程序被剔除的方式。当您使用控制台模板时,您有一个将在控制台中启动的存根。如果您已经在控制台中运行,它会忽略启动控制台的调用。
出于同样的原因,Windows 应用程序设计有默认表单。如果你想清除它,你可以创建一个无窗体的 Windows 窗体应用程序,它本质上是一个没有控制台窗口的控制台应用程序。
就应用程序的内容而言,它们本质上是相同的。主要区别是在编译阶段添加的。
【讨论】:
【参考方案4】:消息循环也是区别之一:
http://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows
【讨论】:
不是可选组件吗?就像您自己编写代码一样,没有任何东西神奇地捆绑到翻译后的二进制文件中......【参考方案5】:您可以使用 EDITBIN.exe (MSDN Entry on EDITBIN.exe) 更改子系统
【讨论】:
引用链接中的重要部分会很有用,以防它不再有效。【参考方案6】:控制台应用程序从 Windows 命令行运行(启动/运行/cmd)
预设了一个 Window 应用程序,因此您可以编写一个在 Windows 环境中运行的 GUI 应用程序。
【讨论】:
【参考方案7】:控制台应用程序的入口点是 wmain
(自 Visual Studio 2008 IIRC 起),如果您选择退出默认 Unicode,则为 main
。对于台式机,它是wWinMain
/WinMain
。
这并不是说这些技术是相互排斥的。控制台应用程序仍然可以使用整个 Win32 API,桌面应用程序可以使用控制台 I/O(但它们必须先显式创建一个控制台窗口)。
【讨论】:
以上是关于Windows 和控制台应用程序之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
控制台 (/SUBSYSTEM:CONSOLE) 和 Windows (/SUBSYSTEM:WINDOWS) 之间的区别
Win32 Application和Win32 Console Application区别
WindowsApplication和ConsoleApplication有啥区别