问题 如何在不显示Win32 GUI程序的控制台窗口的情况下执行子控制台程序?


(我搜索了SO的答案,发现这个问题没有明确的解决方案。)

我正在研究MFC GUI程序。该程序运行各种子程序,包括控制台程序和shell命令脚本(.cmd)。

最初它显示了一个GUI窗口和一个控制台窗口(使用 AllocConsole)因为子进程有很多控制台输出。但许多用户抱怨控制台窗口,所以我们决定隐藏控制台窗口。

首先尝试如下:

if (AllocConsole())
{
    ::ShowWindow(::GetConsoleWindow(), SW_HIDE);
}

好的,没有控制台窗口,但在控制台创建时有可见的闪烁。 我试了好几个 CreateProcess 子进程创建的选项,以防止完全显示控制台窗口,但总之失败,我认为这几乎是不可能的。

这不是什么大不了的事。我们可以在启动时忽略临时窗口闪烁。

但完全隐藏儿童游戏机窗口真的不可能吗?


8919
2018-01-20 04:51


起源

预计闪烁;你正在创建一个控制台窗口然后隐藏它。问题是,如果您不希望用户看到它,为什么要创建一个控制台窗口?怎么了? ShellExecute 要么 CreateProcess? - Cody Gray♦
@Code Gray这个程序CreateProcess各种控制台程序。如果没有AllocConsole,将创建分离和不可控制的控制台窗口,并一直销毁。 - 9dan
我不知道这意味着什么。你正在运行几个 不同 控制台程序,如果你使用 CreateProcess 每次都会创建一个新的控制台窗口,而不是重用旧的控制台窗口?所以啊?这有什么问题? - Cody Gray♦
@Code Gray你最好重读标题。我想在不显示控制台窗口的情况下执行子控制台程序。 - 9dan
问题是,我不知道“儿童控制台程序”是什么。我仔细阅读了标题,刚才再次阅读。您只是询问如何使子控制台窗口不可见。如果用户不需要能够与在该控制台窗口中运行的程序进行交互,我就会质疑你为什么需要这个窗口(你的问题表明你最初认为是这种情况,但后来发生了变化)你的设计)。仍然不清楚为什么你运行的这些控制台应用程序都需要从中启动 相同 控制台窗口。 - Cody Gray♦


答案:


为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;

15
2018-01-20 06:38



谢谢!当使用带有CREATE_NO_WINDOW选项的CreateProcess时,它可以正常工作。 - 9dan
@Cody Gray:问题是这样的 CreateProcess 本身是不够的,而不是它是错的。 I / O重定向和 CREATE_NO_WINDOW 还需要国旗。 - MSalters
在 C# 使用 ProcessStartInfo 并设置 WindowStyle = ProcessWindowStyle.Hidden。几乎与.NET Framework相同。 - Bitterblue