隐藏Windows应用程序的控制台

69

我有一个Qt应用程序,当我运行它时,会在其后面打开一个控制台窗口。在开发过程中,这很好,因为我可以在控制台上看到调试输出,但是当我想将可执行文件交给客户时,就不应该有控制台窗口。

我该如何隐藏它?

(我正在使用Visual Studio 2008)


最好的方法是创建一个QT项目并使用QVTKWidget。 - Orochi
13个回答

160
在项目构建的链接器选项中设置。
/SUBSYSTEM:windows
/ENTRY:mainCRTStartup

或者在带有int main(...)的源文件中使用以下的#pragma

#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")

11
在我看来,这是一份既包含子系统部分处理又包含不同入口点部分处理的最佳而且简明扼要的答案。小的Unicode提示:如果你使用Unicode编译,并且使用wmain而非main,则注释应为“/ENTRY:wmainCRTStartup”。 - Cray
2
@GuyJoelMcLean:专业提示:如果您需要稍后进行调试的控制台,则可以使用AllocConsole http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944(v=vs.85).aspx - datenwolf
2
在VS 2010中,#pragma对我无效。我必须通过项目属性设置这两个选项,从预处理器中删除_CONSOLE。然后重新构建,就可以完美地运行了。 - John Neuhaus
1
这应该是被接受的答案。例如,如果你正在Windows上使用CMake进行开发,这是唯一的选择。此外,它可以移植到其他窗口系统,如GLFW、SDL等。 - alexpanter
1
这非常有帮助! - Noah.Ehrnstrom
显示剩余4条评论

71

听起来你的链接器配置不正确。右键单击项目,属性,链接器,系统,子系统设置。确保选择了“Windows”,而不是“控制台”。

同时,将main()更改为WinMain()。


1
main()和WinMain()之间有什么区别吗? - ufukgun
8
您可以在属性 -> 链接器 -> 高级选项 -> 入口点 中将项目的入口点设置为标准的 main() - Jan Turoň
2
问题在于,当我在Windows中运行程序时,即使我解决了main/WinMain的问题,它仍然无法终止。 - Tomáš Zato
@JanTuroň 怎么做?我们在那个字段中放什么选项?它是一个字符串字段,我尝试了很多种解决方案,但都没有起作用。 - anon
@NicHartley,回到2008年,它应该是一个选择框。也许在配置中有其他设置。您可以提出另一个问题,并提供逐步设置以重现该问题吗? - Jan Turoň

24

调用以下代码可以去掉控制台:

FreeConsole();

你需要 #include <Windows.h> 来实现这个。 - Superior

14

我使用了该方法,它起作用了。

HWND hwnd = GetConsoleWindow();
ShowWindow(hwnd, 0);

6
如果您从命令行启动程序,命令行窗口会消失。FreeConsole不会出现这个问题。 - nwp

10
下一个解决方案 ;)
环境: WixXP x64, msvs 2008, Qt v4.5.3
  1. Set Projects settings/Configuration properties/Linker/System/SubSystem = Windows (/SUBSYSTEM:WINDOWS)

    But For x64 there is linker error: LNK2019: unresolved external symbol _WinMain referenced in function _WinMainCRTStartup" To avoid it

  2. Replace the following code:

    int main(int argc, char *argv[])
    {
         QApplication app(argc, argv);
         // your code*
    }
    

    by

    int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd)
    {
        int argc = 0;
        QApplication app( argc, 0 );
     }
    

它在Win32和x64平台上都可以正常运行。


1
这种方法会防止程序从命令行获取参数。非常、非常糟糕的想法。如果你想正确地做到这一点,应该对WinMain的第三个参数接收到的字符串进行分词。是的,有很多Windows程序解释命令行参数。例如,在Windows资源管理器中,“打印”上下文菜单启动一个带有命令行参数的程序。 - datenwolf
datenwolf,他们仍在使用__argv和__argc宏(至少在MSVC中),或者GetCommandLine/CommandLineToArgv winapi函数。 - Cray
这对我解决了问题。非常感谢 :)) - Tayab

6
也许更好的选择不是简单地删除(如Andy M所建议的),而是编辑*.pro文件,添加类似以下内容:
CONFIG(debug, debug|release) {
    CONFIG *= console
} 
else {
    CONFIG -= console
}

在调试模式下你可以看到控制台窗口,但在发布模式下却看不到。我喜欢这样。=)


6
如果你使用 属性->链接器->系统->子系统 | Windows 并且收到链接器错误,你可以查看 链接器->高级->入口点 并将值设置为你的“main”函数的名称。也就是说,如果你的主函数是“main”,那么你的入口点就变成了 main。

4
我建议您检查您的.PRO文件中是否存在以下行:
CONFIG += console

如果您能找到它,请将其移除!这应该可以解决您的问题!希望对您有所帮助!

实际的Visual Studio项目是使用QMake项目文件中的配置参数创建的,因此这很可能是原因。 - Veeti
在VCProj属性中,可能通过进入链接编辑、系统,最后是子系统...尝试将值设置为“Windows (/SUBSYSTEM:WINDOWS)”...不过我不确定你是否可以这样做... - Andy M
1
我在我的一个应用程序中进行了快速测试,由于某些不明原因,我需要添加以下库:c:\ ... \ Qt \ 4.6.0-vs2008 \ lib \ qtmain.lib在VCProj属性->链接编辑->条目->附加依赖项中。 - Andy M
1
看起来这是最终解决方案 :) - Andy M

2

如果您直接编辑.vcxproj文件,您需要在 中添加一个值为WindowsSubSystem,具体如下:

<ItemDefinitionGroup>
  <Link>
    <SubSystem>Windows</SubSystem>
  </Link>
</ItemDefinitionGroup>

0

步骤1:设置属性 -> 链接器 -> 系统 -> 子系统为“Windows (/SUBSYSTEM:WINDOWS)”
步骤2:链接器 -> 高级 -> 入口点为“main”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接