【问题标题】:Difference between Windows and Console applicationWindows 和控制台应用程序之间的区别
【发布时间】:2009-02-22 13:17:35
【问题描述】:

Windows 和控制台应用程序有什么区别?

在 Visual C++ 中创建新项目时,它会要求选择上述任何一个。

【问题讨论】:

    标签: 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】:

        【讨论】:

        • 不是可选组件吗?就像您自己编写代码一样,没有任何东西神奇地捆绑到翻译后的二进制文件中......
        【解决方案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(但它们必须先显式创建一个控制台窗口)。

          【讨论】:

            猜你喜欢
            • 2017-06-21
            • 1970-01-01
            • 1970-01-01
            • 2014-01-02
            • 1970-01-01
            • 1970-01-01
            • 2017-01-16
            • 2011-08-12
            • 1970-01-01
            相关资源
            最近更新 更多