Process created with CreateProcessAsUser won't initialize properly
Some time ago a customer of mine had an issue with his client/server application when using CreateProcessAsUser. The process that they were creating was starting but closing immediately and unexpectedly without executing a single line of code in its "main" function. This was the scenario:
- The client connected to the server via named pipe.
- The server impersonated the client (with ImpersonateNamedPipeClient API).
This scenario was working fine on Windows XP and Server 2003, but not on Vista, Server 2008, Win7 & Server 2008 R2.
We tried to debug the launched process, without much success. When we tried to attach a debugger like cdb.exe or windbg.exe (Debugging Tools for Windows) when the process started, those debuggers failed to start too. When we tried to attach ntsd.exe debugger (Debugging Tools for Windows), the launched process worked just fine, so we couldn't repro the issue. Ntsd.exe made the issue to go away.
Then we verified with Process Monitor that the launched process was indeed starting, but closed before finishing its initialization, while it was loading dlls like kernelbase.dll.
It turned out that we were calling CreateProcessAsUser without any of these flags, so the child process was inheriting the console from the parent by default:
CREATE_NEW_CONSOLE0x00000010 The new process has a new console, instead of inheriting its parent's console (the default). For more information, see Creation of a Console.
This flag cannot be used with DETACHED_PROCESS.
CREATE_NO_WINDOW0x08000000 The process is a console application that is being run without a console window. Therefore, the console handle for the application is not set.
This flag is ignored if the application is not a console application, or if it is used with either CREATE_NEW_CONSOLE or DETACHED_PROCESS.
DETACHED_PROCESS 0x00000008 For console processes, the new process does not inherit its parent's console (the default). The new process can call the AllocConsole function at a later time to create a console. For more information, see Creation of a Console.
This value cannot be used with CREATE_NEW_CONSOLE.
Inheriting the console from the parent will fail since both processes, the windows service and the launched process, run in different sessions. The console cannot be shared between sessions.
Now, this used to work in versions of Windows older than Vista as there was no "session 0 isolation", so both the service and the launched process were running in the same session:
In Windows XP, Windows Server 2003, and earlier versions of Windows, all services run in Session 0 along with applications
We tried calling CreateProcessAsUser with each of these flags: CREATE_NEW_CONSOLE, CREATE_NO_WINDOW & DETACHED_PROCESS, and any of them made things work. You would have to choose one of those flags depending on your needs: Creation of a Console.
I hope this helps.
Alex (Alejandro Campos Magencio)