如何隐藏win32 console application的console窗口

来源:互联网 发布:老舍的人品 知乎 编辑:程序博客网 时间:2024/04/27 12:28

一    subsystem和可执行文件的启动
LINK的时候需要指定/subsystem,这个链接选项告诉Windows如何运行可执行文件。


我们知道用VC编写的程序,运行的时候是需要 C/C++运行库支持的.当我们运行一个C/C++程序的时候
链接器会首先寻找应用程序的启动函数,例如:


如果你建立了一个console程序的话,编译器得链接开关会是以下这种形式
/subsystem:"console" /entry:"mainCRTStartup"   (ANSI)
/subsystem:"console" /entry:"wmainCRTStartuup" (UNICODE)

将 subsystem 选成"console"后,Windows在进入可执行文件的代码前(如mainCRTStartup),就会产生一个控制台窗口。之后mainCRTStartup 或 wmainCRTStartuup 会调用main或wmain。

 

如果你建立了一个win32 application,编译器得链接开关则会是一下形式
/subsystem:"windows" /entry:"WinMainCRTStartup"   (ANSI)
/sbusystem:"windows" /entry:"wWinMainCRTStartup" (UINCODE)

将 subsystem 选成"console"后,操作系统就不产生console窗口,该类型应用程序的窗口由用户自己创建。WinMainCRTStartup 或 wWinMainCRTStartup 会调用 WinMain 或 wWinMain。

 

值得一提的是,在进入应用程序的Entry Point前,Windows的装载器已经做过C变量的初始化,有初值的全局变量拥有了它们的初值,没有初值的变量被设为0。

 

二    隐藏console窗口

       有两种方法:

1    在默认情况下/subsystem 和/entry开关是匹配的,也就是:
"console"对应"mainCRTStartup"或者"wmainCRTStartup "
"windows"对应"WinMainCRTStartup "或者"wWinMainCRTStartup "
我们可以通过手动修改的方法使他们不匹配。例如:

#include "windows.h"
#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" ) // 设置入口地址
void main(void)
{
MessageBox(NULL, "hello", "Notice", MB_OK);
}

这个Console程序就不会显示Console窗口。

上面是在代码中使用#pragma指令来设置,还有一种就是直接在开发环境的
project->setting->link->project option中手工改动!

 

2    还有一个更直接的方法:那就是直接在EXE文件中将PE文件头的Subsystem从3改成2。在EXE文件中,PE文件头的偏移地址是0x3c,Subsystem是一个WORD,它在PE文件头中的偏移是0x5c。