C++如何在启动时隐藏控制台窗口?

29

我想知道如何在启动时隐藏控制台窗口。

这是一个键盘记录程序,我的意图不是去黑别人。这是一个小型学校项目,我想用它来展示黑客的危险。

这是我目前的代码:

#include <cstdlib>
#include <iostream>
#include <Windows.h>

using namespace std;

int main()
{

    cout << "Note. This program is only created to show the risk of being unaware of hackers." << endl;
    cout << "This program should never be used to actually hack someone." << endl;
    cout << "Therefore this program will never be avaiable to anyone, except me." << endl;

    FreeConsole();

    system("PAUSE");
    return 0;
}

我看到在启动时出现了一个窗口,然后立即消失。似乎接着会打开一个全新的控制台,里面什么也没有。(我指的是"按任意键继续...",我想知道这是否与system("PAUSE")有关?)

所以我想知道为什么它会打开一个新的控制台,而不是只创建并隐藏第一个控制台。

谢谢 :)


1
system 会生成一个新的 shell。 - Rapptz
8
不要将它写成控制台程序。只需编写一个没有窗口的 WinMain(),使用消息框或模态对话框来显示屏幕垃圾信息。 - WhozCraig
你必须在链接器选项中指定子系统。 - chris
10个回答

42

如果您希望根据需要隐藏/显示控制台窗口,可以使用以下功能: 通过ShowWindow函数可以隐藏/显示控制台。使用GetConsoleWindow可获取控制台使用的窗口句柄。 IsWindowVisible可用于检查窗口(在此为控制台)是否可见。

#include <Windows.h>

void HideConsole()
{
    ::ShowWindow(::GetConsoleWindow(), SW_HIDE);
}

void ShowConsole()
{
    ::ShowWindow(::GetConsoleWindow(), SW_SHOW);
}

bool IsConsoleVisible()
{
    return ::IsWindowVisible(::GetConsoleWindow()) != FALSE;
}

1
使用SW_MINIMIZE代替SW_HIDE,可以使控制台隐藏但仍可在任务栏中显示。 - nikau6
你好nikau6,很高兴收到你的回复。现在我从阅读你的帖子中获得了更多的收获。然而,我想要的是完全隐藏控制台。你原始发布的代码起了奇效。它按照我的意愿工作。我用它来弹出一个GUI,因此我想让控制台完全隐藏,即使不在任务栏上也看不到。非常棒的帖子。再次感谢你。 - coarist

22

在你的代码中启动时隐藏控制台窗口并不是真正可能的,因为可执行文件由操作系统以特定设置运行。这就是为什么在启动时使用 FreeConsole(); 时控制台窗口会短暂地显示。

要在启动时真正隐藏窗口,您必须向编译器添加特殊选项。如果您在Windows(MinGW)上使用gcc,则可以在makefile中添加-mwindows作为编译器选项,这样就不会有任何窗口或“闪烁”。

我不清楚Visual Studio或您目前使用的任何工具,但改变IDE编译代码的方式是正确的做法,而不是在C++中编写解决方法。

在我看来,这种方法比使用WinMain更好,因为它可靠且不会使您的C++代码依赖于特定平台。


5
编译器标志是解决问题的方法。对于Visual Studio,您可以参考此答案 - Arnaud

13
#include <windows.h>
ShowWindow(GetConsoleWindow(), SW_HIDE); //SW_RESTORE to bring back

这将返回一个窗口句柄(HWND)给ShowWindow(),而后者将隐藏它。此解决方案仅适用于Windows系统。

即使没有被标记,这是正确的答案。

编辑:一种可能的解决方案/黑客方法是在Visual Studio中设置链接器->系统->子系统为"Windows (/SUBSYSTEM:WINDOWS)"而不是"Console (/SUBSYSTEM:CONSOLE)"。然而,这可能不是最优的解决方案。


7
#include <windows.h>
#include <iostream.h>

void Stealth()
{
 HWND Stealth;
 AllocConsole();
 Stealth = FindWindowA("ConsoleWindowClass", NULL);
 ShowWindow(Stealth,0);
}

int main()
{
  cout<<"this sentence is visible\n";
  Stealth(); //to hide console window
  cout<<"this sentence is not visible\n";
  system("PAUSE"); //here you can call any process silently like system("start chrome.exe") , so google chrome will open and will surprise user..
  return EXIT_SUCCESS;
}

5

这很简单。使用FreeConsole() API可以为你完成这个神奇的操作。

BOOL WINAPI FreeConsole(VOID);

5
我想知道为什么它会打开一个新的控制台,而不是只创建并隐藏第一个控制台。
控制台应用程序实际上并不会自己创建控制台,它只是在其中运行。如果你从资源管理器中运行可执行文件,Windows会为其创建一个控制台以供运行。当你调用FreeConsole时,它不会关闭新的控制台,只是将你的进程与其分离。
正如WhozCraig在评论中提到的那样,请创建一个常规的Windows应用程序,并且不要创建窗口。

5

3
只需在启动时执行即可。
myConsole = GetConsoleWindow();
ShowWindow(myConsole,0);

自动获取控制台窗口: auto myConsole = GetConsoleWindow(); ShowWindow(myConsole, 0); 完成啦 :D - Charlie
1
这个程序的动态类型非常强大。 - Ch3shire

3

只需将您的应用程序类型从“控制台应用程序”更改为“Windows应用程序”(并将您的main更改为WinMain)。在这种情况下,您的应用程序将完全不需要控制台窗口即可启动。


-1

8年后哈哈

但是

对于您的项目来说,一个简单的解决方案就是使用 .vbs 文件。

Dim WShell
Set WShell = CreateObject("WScript.Shell")
WShell.Run "xr.exe", 0
Set WShell = Nothing

这段代码会在运行时启动xr.exe并将其隐藏起来,但是Windows Defender误认为它是病毒。


3
问题是关于C++的。 - shr

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