CreateProcess does not create additional console windows under Windows 7?

我怕爱的太早我们不能终老 提交于 2019-12-03 17:31:19
Joker_vD

MSDN is really your best friend while working with Win32 API. Now, the relevant creation flags for you are the following:

(no flags set) — the child process (the one being started with CreateProcess()) will share the console with the parent process (the process which called CreateProcess()).

CREATE_NEW_CONSOLE — the child process will receive a new console, open in a new window. As the MSDN explicitly says, this flag MUST NOT be used together with DETACHED_PROCESS! And that's exactly the flag that you want to use.

CREATE_NO_WINDOW — the child process will receive a new console, but without any window for it. That's quite a surprising flag, so I will restate it again: the child process will have a console, to which you can write your output, from which you can try to read input, etc; this console is different from the parent process's console; this console is invisible, it has no visible window, but it exists. It's useful for, say, silently running child processes in background. Note that this flag has no effect when used with CREATE_NEW_CONSOLE or DETACHED_PROCESS — those flags override this one. Also keep in mind that this flag is ignored when you launch a GUI application: it won't receive an invisible console.

DETACHED_PROCESS — the child process will not receive any console whatsoever. You must not use this flag together with CREATE_NEW_CONSOLE.

And now a bit more about correct invocation of CreateProcess(). First of all, you should use CreateProcessW(). I am particularly tired of apps that can't access files in a directory named 日本語αβηλ.

Second, even if you use the ANSI version, specify CREATE_UNICODE_ENVIRONMENT flag if you pass NULL for the environment. If you don't do this, PATH may end up broken in the child process, and this bug is extremely annoying to trace down.

Third, don't const_cast<char*>command.c_str(). Just call strdup()/wcsdup() on it, and then free() after the CreateProcess() call returned. Or if you really insists on modifying command in place, pass &command[0] as the parameter.

Fourth, don't forget to set the size of your STARTUPINFO structure: startupInfo.cb = sizeof(startupInfo). Modern Windows (XP and 7, at least) actually allow you to leave this field to be a zero without any harmful consequences, but it's a bit of a sloppy programming to rely on this.

Oh, and while we are here: you mentioned that you use CreateProcess() because, among other things, it allows you to specify environment for the child explicitly. Well, there is a slight gotcha about lpEnvironment parameter which is documented, but quite easily overlooked. When you specify NULL, the child inherits the parent's environment. When you specify something non-NULL, the parent's environment IS NOT ADDED to it. If you want to add to the parent's environment, you'd have to use GetEnvironmentStrings() to obtain it and then explicitly tweak it.

Pass CREATE_NEW_CONSOLE in the dwCreationFlags when calling CreateProcess. I have not tested, but I suspect this forces the creation of a console window (perhaps even for non-console processes?) You could also use DETACHED_PROCESS instead, which merely detaches from the parent console.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!