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 结构。这有一个名为Subsystemint161) 成员。 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有啥区别

Windows Azure 和 Windows IIS 之间的确切区别是啥?

在单独的控制台和 Windows 应用程序之间传递信息

通过 Windows 10“设置”应用程序和旧版控制面板卸载应用程序有啥区别? [关闭]