Windows下如何才能不显示控制台(终端)窗口?
点击编译好的exe文件,显示GUI程序窗口的同时会显示一个显示标准输出的终端窗口。我的程序是要打包给客户使用的,显示一个终端窗口肯定是不行的! 如何才能不显示这个终端窗口?我把编译配置里的 “-D_CONSOLE”选项都去掉了,还是有个终端窗口。
定义宏NDEBUG即可。
#if defined(WIN32) && !defined(NDEBUG)
#define TK_ENABLE_CONSOLE() \
{ \
AllocConsole(); \
FILE* fp = NULL; \
freopen_s(&fp, "CONOUT$", "w+t", stdout); \
}
#else
#define TK_ENABLE_CONSOLE()
#endif /*WIN32 && !NDEBUG*/
定义宏NDEBUG即可。
#if defined(WIN32) && !defined(NDEBUG) #define TK_ENABLE_CONSOLE() \ { \ AllocConsole(); \ FILE* fp = NULL; \ freopen_s(&fp, "CONOUT$", "w+t", stdout); \ } #else #define TK_ENABLE_CONSOLE() #endif /*WIN32 && !NDEBUG*/
我是用msys2里的mingw来编译的,加了NDEBUG宏发现还是一样有终端窗口。
应该是在自己的应用程序里定义。
应该是在自己的应用程序里定义。
我现在使用的是awtk_main.inc里的application_init函数作为入口。看了下awtk_main.inc源码,如果编译器是mingw的话程序的入口是main函数而非GUI程序的WinMain之类,所以必定会有控制台窗口。 我没什么win32 api的编程经验,搞这个还要花点时间,建议官方在awtk_main.inc里就做好WinMain入口。
这其实算是一个BUG,我的APP类型都已经定成 APP_DESKTOP了,但实际编译出来的却是console类型程序。
确实有一个BUG:如果编译器是msys2(MSYS2)里的mingw,即使程序的入口是WinMain(或wWinMain),编译出来的GUI程序在双击运行时依然会显示一个控制台(console)窗口;只有添加链接器选项 -Wl,-subsystem,windows显式指定windows子系统后才不会显示控制台窗口。
PS:AWTK到这个阶段了还有这种BUG,说明用AWTK的人真的不多……
好的,谢谢。用mingw编译的人比较少。
mingw 是不能用 WinMain(或wWinMain) 作为程序入口的,只能使用 main 函数作为入口的,而原来的 main 部分的逻辑,是没有处理控制台窗口的,最新的代码会统一了 windows 下的控制台窗口的处理逻辑,可以通过 _CONSOLE 和 NDEBUG 以及程序第 3 个传参来开关控制台窗口。
mingw 是不能用 WinMain(或wWinMain) 作为程序入口的,只能使用 main 函数作为入口的,而原来的 main 部分的逻辑,是没有处理控制台窗口的,最新的代码会统一了 windows 下的控制台窗口的处理逻辑,可以通过 _CONSOLE 和 NDEBUG 以及程序第 3 个传参来开关控制台窗口。
你的mingw跟我的不一样么?我用的是MSYS2里的mingw-w64-x86_64。在windows下如果入口为main必定会有控制台窗口。我修改了awtk_main.inc源码来使用WinMain作为入口、不执行TK_ENABLE_CONSOLE()函数,并且必须加-Wl,-subsystem,windows链接选项才不会有控制台窗口。
好的,谢谢。用mingw编译的人比较少。
我最初也是尝试用MSVC编译的,但编译失败,似乎MSVC这东西不同版本间有差异,所以才换成mingw
哦,重新测试了下,发现我之前的说法有误。修改awtk_main.inc源码,所有测试用例都不执行TK_ENABLE_CONSOLE()函数,mingw为MSYS2里的mingw-w64-x86_64:
- 入口函数
WinMain、无-Wl,-subsystem,windows链接器选项:有控制台窗口 - 入口函数
WinMain、有-Wl,-subsystem,windows链接器选项:无控制台窗口 - 入口函数
main、无-Wl,-subsystem,windows链接器选项:有控制台窗口 - 入口函数
main、有-Wl,-subsystem,windows链接器选项:无控制台窗口
看来有无控制台与入口函数无关而与-Wl,-subsystem,windows链接器选项有关。
我昨天测试了在 MSYS2 里的 mingw-w64-x86_64 或者直接使用 mingw64 编译入口函数为 WinMain,会在链接的时候都会出错,找不到 WinMain 函数。 我的理解在 mingw 上面就不应该有 WinMain 函数,因为 WinMain 函数是属于 windows 的东西来的。 正常来说用 vs 来编译应该可以正常编译才对的,不应该出现问题的把。
我昨天测试了在 MSYS2 里的 mingw-w64-x86_64 或者直接使用 mingw64 编译入口函数为 WinMain,会在链接的时候都会出错,找不到 WinMain 函数。 我的理解在 mingw 上面就不应该有 WinMain 函数,因为 WinMain 函数是属于 windows 的东西来的。 正常来说用 vs 来编译应该可以正常编译才对的,不应该出现问题的把。
找不到WinMain是因为awtk_main.inc里没有这个函数而有unicode版的wWinMain,改下原型即可。
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
str_t str;
int argc = 1;
char* argv[MAX_ARGV];
#ifdef _CONSOLE
bool_t enable_console = TRUE;
#else
bool_t enable_console = FALSE;
#endif
int32_t lcd_w = LCD_WIDTH;
int32_t lcd_h = LCD_HEIGHT;
str_init(&str, 0);
str_set(&str, lpcmdline);
command_line_to_argv(str.str, argv, &argc);
要深入研究入口函数的话最好要看下编译器所使用的启动代码了,似乎Qt在用mingw编译GUI程序时也会指明使用WinMain入口。
今天测了下,即使入口函数是main,只要在链接时指定windows子系统也没有控制台窗口,所以mingw用main是要稳妥点。
你的意思是 mingw 是有 wWinMain 函数,没有 WinMain 函数?
不是。mingw想链接WinMain,但你源码里没有这个函数,awtk/src/awtk_main.inc文件里有wWinMain。可以将wWinMain原型改为WinMain对应的原型。
嗯嗯,明白了,谢谢