(我搜索了很多答案,但没有找到解决这个问题的明确解决方案。)
我正在开发 MFC GUI 程序。该程序运行各种子程序,包括控制台程序和shell命令脚本(.cmd)。
最初它显示了一个 GUI 窗口和一个控制台窗口(使用
AllocConsole
创建),因为子进程有很多控制台输出。但许多用户抱怨控制台窗口,因此我们决定隐藏控制台窗口。
首先尝试如下:
if (AllocConsole())
{
::ShowWindow(::GetConsoleWindow(), SW_HIDE);
}
好吧,没有控制台窗口,但在控制台创建时有明显的闪烁。 我已经尝试了几个用于创建子进程的
CreateProcess
选项来完全阻止显示控制台窗口,但很快就失败了,我认为这实际上是不可能的。
这没什么大不了的。我们可以忽略启动时的临时窗口闪烁。
但是完全隐藏子控制台窗口真的不可能吗?
为 CreateProcess 调用设置 STARTUPINFO:
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.wShowWindow = SW_HIDE;
CREATE_NO_WINDOW是关键,在我的测试中,它还将进程与父进程分离,以便子进程在父进程死亡后幸存下来,这是一个僵尸进程。
#include <windows.h> // What would I do without you
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi;
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
if (!CreateProcess(
NULL, // [in, optional] LPCSTR lpApplicationName,
s_command, // [in, out, optional] LPSTR lpCommandLine,
NULL, // [in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
NULL, // [in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
FALSE, // [in] BOOL bInheritHandles,
CREATE_NO_WINDOW, // [in] DWORD dwCreationFlags,
NULL, // [in, optional] LPVOID lpEnvironment,
NULL, // [in, optional] LPCSTR lpCurrentDirectory,
&si, // [in] LPSTARTUPINFOA lpStartupInfo,
&pi // [out] LPPROCESS_INFORMATION lpProcessInformation
)){
print("Failed to create process\n");
return 1;
}
// Wait until child process exits.
// WaitForSingleObject( pi.hProcess, INFINITE );
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
print("Succeded to create process\n");
感谢上面@9dan 的评论。