How to execute child console programs without showing the console window from the Win32 GUI program?
Asked Answered
W

2

11

(I've searched SO answers and found no clear solution to this problem.)

I'm working on a MFC GUI program. This program runs various child programs including console program and shell command script(.cmd).

Initially it displayed one GUI window and one console window (created with AllocConsole) because there are many console output from the child processes. But many users complained about the console window so we decided to hide the console window.

Firstly tried like below:

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

Okay, no console window but there are visible flicker at the console creation time. I've tried several CreateProcess options for child process creation to prevent showing of console window altogether but failed at short and I think it is practically impossible.

It is not a big deal. We can ignore temporary window flicker at the startup.

But is it really impossible to hide child console window completely?

Wuhsien answered 20/1, 2011 at 4:51 Comment(8)
The flicker is expected; you're creating a console window and then hiding it. The question is, why do you create a console window at all, if you don't want the user to see it? What's wrong with ShellExecute or CreateProcess?Christiansen
@Code Gray This program CreateProcess various console programs. Without AllocConsole, separated and uncontrollable console window will be created, destroyed all the time.Wuhsien
I have no idea what that means. You're running several different console programs, and if you use CreateProcess each time will create a new console window instead of reusing the old one? Yeah...so? What's wrong with that?Christiansen
@Code Gray You'd better reread the title. I want to execute child console programs without showing the console window.Wuhsien
The problem is, I don't know what "child console programs" are. I read the title carefully, and just now again. You are only asking how to make a child console window invisible. I'm questioning why you need the window at all, if the user doesn't need to be able to interact with the program running in that console window (your question indicates that you originally thought this to be the case, but have since changed your design). It's still not at all clear why these console applications you're running all need to be started from the same console window.Christiansen
Changed the title to avoid confusion.Wuhsien
@Alf: See my comments above. I've already suggested this, but apparently there's something secret about what the OP is trying to do that involves running all of the console applications in the same console window, but requiring it to be hidden as if it didn't exist at all. Confused? Me too.Christiansen
@Cody, @Alf The point is not on the executing/CreateProcess but on the create console process invisibly. I'm sorry if this confused you that much. But I don't think your comments have any positive values. Almost spamming. I said this is already completed program. How the hell do you suppose to build such a program without calling CrateProcess ?? What did you mean with CreateProcess is really confusing me. Did you found CreateProcess some day before today? So wanted to sharing the knowledge with me?Wuhsien
T
16

Setup the STARTUPINFO like this for the CreateProcess call:

    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;
Toboggan answered 20/1, 2011 at 6:38 Comment(3)
Thank you! It works perfectly when use CreateProcess with CREATE_NO_WINDOW option.Wuhsien
@Cody Gray: the problem is that CreateProcess by itself is insufficient, not that it's wrong. The I/O redirection and the CREATE_NO_WINDOW flag were also needed.Angulation
In C# use ProcessStartInfo and set WindowStyle = ProcessWindowStyle.Hidden. Pretty much the same just .NET Frameworked.Alburga
C
0

CREATE_NO_WINDOW is the key, in my tests, it also detaches the process from the parent so that the child survives the parent death, a Zombie process.

#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");

Thanks to @9dan comment above.

Coastwise answered 8/5, 2024 at 5:42 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.