MSDN is truly your best friend when working with the Win32 API. Now the corresponding creation flags for you are as follows:
(no flags set) - the child process (the one that starts with CreateProcess() ) will share the console with the parent process (a process called CreateProcess() ).
CREATE_NEW_CONSOLE - the child process will receive a new console, will open in a new window. As MSDN explicitly says, this flag MUST NOT be used with DETACHED_PROCESS ! . And it is this flag that you want to use.
CREATE_NO_WINDOW - the child process will receive a new console, but without it. This is a rather amazing flag, so I will repeat it again: the child process will have a console to which you can write your output, from which you can try to read the input, etc .; This console is different from the parent console. this console is invisible, it does not have a visible window, but it exists. This is useful, for example, for seamlessly running child processes in the background. Please note that this flag does not work when used with CREATE_NEW_CONSOLE or DETACHED_PROCESS - these flags override this flag. Also keep in mind that this flag is ignored when starting the GUI application: it will not receive an invisible console.
DETACHED_PROCESS - the child process will not receive any console. You should not use this flag with CREATE_NEW_CONSOLE .
And now a little more about the right call to CreateProcess() . First of all, you should use CreateProcessW() . I am particularly tired of applications that cannot access files in a directory named 日本語αβηλ .
Secondly, even if you are using the ANSI version, specify the CREATE_UNICODE_ENVIRONMENT flag if you pass NULL for the environment. If you do not, PATH may end up broken in the child process, and this error is extremely unpleasant for tracking.
Thirdly, not const_cast<char*>command.c_str() . Just call strdup()/wcsdup() on it, and then free() after calling CreateProcess() . Or, if you really insist on modifying command in place, pass &command[0] as a parameter.
Fourth, remember to set the size of your STARTUPINFO structure: startupInfo.cb = sizeof(startupInfo) . Modern Windows (at least XP and 7) allow you to leave this field zero without any harmful consequences, but this is a bit sloppy programming to rely on.
Oh, and while we're here: you mentioned that you use CreateProcess() , because, among other things, it allows you to explicitly specify the environment for the child. Well, there is little information about the lpEnvironment parameter, which is documented, but quite easily overlooked. When you specify NULL , the child inherits the parent environment. When you specify something that is not NULL , the parent environment DOES NOT ADD to it. If you want to add a parent environment, you will need to use GetEnvironmentStrings() to get it, and then explicitly configure it.