如何在给定 PID 的情况下隐藏进程的控制台?

Posted

技术标签:

【中文标题】如何在给定 PID 的情况下隐藏进程的控制台?【英文标题】:How to hide the console of a process given its PID? 【发布时间】:2017-09-12 14:18:09 【问题描述】:

当我单击 Qt 应用程序上的按钮时,我想启动一个进程。 我使用QProcess::startDetached(..., qint64 * pid) (http://doc.qt.io/qt-5/qprocess.html#startDetached) 创建了一个进程,但我有一个想要隐藏的控制台。

如何隐藏?我必须在流程之外使用哪个功能?

此代码不会隐藏我的进程的控制台(在 win32 中):

if (AttachConsole((DWORD)m_PID))

    FreeConsole();

【问题讨论】:

【参考方案1】:

如果你可以重新编译你正在启动的程序,你可以把它变成一个 Windows 而不是控制台程序(在 MSVC 中,这是在项目链接器->系统,设置中,你想要/SUBSYSTEM:WINDOWS)。

否则 QT start 方法显然永远不会创建控制台窗口,而 startDetached 会创建,因此您可以根据您的使用情况使用 start

另外,CreateProcessCREATE_NO_WINDOW 标志将阻止自动控制台,引用 MSDN:

该进程是在没有控制台窗口的情况下运行的控制台应用程序。因此,未设置应用程序的控制台句柄。

不幸的是,QT 似乎没有提供任何方法来创建或使用带有本机标志或本机句柄(例如,没有 QProcess process(CreateProcess(...)))的 QProcess,尽管它在几年前被建议并被拒绝。 QProcess: Make it possible to set native process creating flags

因此,您要么只使用 Microsoft API,要么为多进程工作寻找另一个库。

【讨论】:

CREATE_NO_WINDOW 是使用 STARTUPINFO 创建隐藏控制台窗口的替代方法。它创建了一个新的控制台(即conhost.exe的实例),进程标准句柄设置为控制台输入和屏幕缓冲区,进程的控制台句柄引用了新的控制台,因此控制台功能正常工作。只是控制台没有创建窗口,所以GetConsoleWindow返回NULLCREATE_NEW_CONSOLE 和任何隐式使用后者的函数(例如 CreateProcessWithLogonWCreateProcessWithTokenW)都会忽略此标志。 是否直接记录在任何地方?文档仅说明“GUI 进程”,但是,“对于 GUI 进程,第一次调用 ShowWindow 时,它的 nCmdShow 参数被忽略 wShowWindow 指定默认值”,但是由于“对于控制台进程,这如果为进程创建了新的控制台,信息会影响控制台窗口。”我猜它被传递到控制台主机并且定义明确,行为略有不同。 如果子进程创建了一个新的控制台,使用STARTUPINFO应该总是有效的,即如果与CREATE_NEW_CONSOLE结合使用。窗口只是隐藏起来的,所以应用程序可以获取它的句柄并显示它。 CREATE_NO_WINDOW 方法隐式地创建了一个新控制台,并且没有可以显示的窗口。至于文档,我不知道作者说“[t] 因此,未设置应用程序的控制台句柄”之类的话有多大意义,这要么是错误的,要么是非常糟糕的陈述。

以上是关于如何在给定 PID 的情况下隐藏进程的控制台?的主要内容,如果未能解决你的问题,请参考以下文章

如何在隐藏控制台的情况下运行 C# 控制台应用程序

如何在给定进程名称的情况下获取 pid

如何在给定表达式的情况下使文本框空白而不是隐藏?

Linux 下如何隐藏自己不被发现?

如何在不隐藏 tabBar 的情况下呈现视图控制器

在没有导航控制器的情况下滑动 Web 视图时如何隐藏工具栏?