如何在给定 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
。
另外,CreateProcess
的 CREATE_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
返回NULL
。 CREATE_NEW_CONSOLE
和任何隐式使用后者的函数(例如 CreateProcessWithLogonW
和 CreateProcessWithTokenW
)都会忽略此标志。
是否直接记录在任何地方?文档仅说明“GUI 进程”,但是,“对于 GUI 进程,第一次调用 ShowWindow 时,它的 nCmdShow
参数被忽略 wShowWindow
指定默认值”,但是由于“对于控制台进程,这如果为进程创建了新的控制台,信息会影响控制台窗口。”我猜它被传递到控制台主机并且定义明确,行为略有不同。
如果子进程创建了一个新的控制台,使用STARTUPINFO
应该总是有效的,即如果与CREATE_NEW_CONSOLE
结合使用。窗口只是隐藏起来的,所以应用程序可以获取它的句柄并显示它。 CREATE_NO_WINDOW
方法隐式地创建了一个新控制台,并且没有可以显示的窗口。至于文档,我不知道作者说“[t] 因此,未设置应用程序的控制台句柄”之类的话有多大意义,这要么是错误的,要么是非常糟糕的陈述。以上是关于如何在给定 PID 的情况下隐藏进程的控制台?的主要内容,如果未能解决你的问题,请参考以下文章