Does CreateProcess not create additional console windows under Windows 7?

I am trying to start a process using CreateProcess (...) and start it myself in a separate console window.

I can achieve this using the system ("...") function, but I prefer CreateProcess, since it gives me the opportunity to specify the environment and working directory, get the process descriptor, as well as piping stdin / out when I need to.

All that I find on the Internet is the reverse problem, which is people who have additional console windows and want to get rid of them! It seems that the usual behavior in earlier versions of Windows opened and a new console window appeared?

Currently, I cannot get an additional window even if I run "cmd.exe / c ..."

I tried using the STARTF_USESHOWWINDOW flag with no luck.

Has anyone had this problem?

PS: A GUI window is displayed, for example. Typically a notepad.exe file is displayed.

This is my code (essentially)

PROCESS_INFORMATION processInfo; STARTUPINFOA startupInfo; ZeroMemory(&startupInfo,sizeof(startupInfo)); startupInfo.dwFlags |= CREATE_NEW_CONSOLE; startupInfo.dwFlags |= DETACHED_PROCESS; ok&=CreateProcessA( NULL, const_cast<char*>(comand.c_str()), // safe for CreateProcessA NULL, NULL, TRUE, NULL, NULL, NULL, &startupInfo, &processInfo); 

I try to run C: /Windows/system32/cmd.exe/c help The program starts and I can read the output from the channel. There is still no window.

+1
source share
2 answers

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.

+10
source

Go CREATE_NEW_CONSOLE to dwCreationFlags when calling CreateProcess . I have not tested it, but I suspect that it forces a console window to be created (perhaps even for non-console processes?) Instead, you can use DETACHED_PROCESS , which is just detached from the parent console.

+2
source

All Articles