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