2

I need to spawn a process which need to invoke UAC. I have read this post: How can I run a child process that requires elevation and wait?.

Unfortunatelly I can't run a process as a real child. The new process run as a separate and continue to run even after spawner close. But I need it to close automatically when parent exits (normal exit or by crash or any other reason).

One of the solution that were provided is to use jobs for that. Unfortunately I can't assign a process created with ShellExecuteEx to a job. It returns me an error ERROR_ACCESS_DENIED. To handle this I have to pass CREATE_BREAKAWAY_FROM_JOB to CreateProcess. And this is the closed circle. I have to use ShellExecuteEx but not CreateProcess.

Community
  • 1
  • 1
nikitablack
  • 4,359
  • 2
  • 35
  • 68
  • 3
    The Windows kernel does not attribute any specific meaning to a *child process*, with the exception of handle inheritance. In particular there is no relationship with respect to process lifetimes (unless explicitly implemented). – IInspectable Jun 30 '15 at 15:54
  • 1
    Windows does not really care about parent/child relationships between processes. Processes are independent of each other. Yes, it is *possible* to know which process spawned another process (Windows does keep track of that info behind the scenes), but it is not really useful information to user code in Windows environments. What exactly are you trying to solve by "running a process as a child"? Just spawn a new process and be done with it. The question MK linked to tells you how to link processes together if you must be able to kill them together - put them in the same Job object together. – Remy Lebeau Jun 30 '15 at 18:32
  • If you don't want the parent process to wait for the "child", don't. Waiting for a launched process to exit is not the default state. – Jonathan Potter Jun 30 '15 at 19:46
  • The title of the question doesn't match the contents. Do you want the process to be your child (and if so, why) or do you want it to *not* be your child? – Harry Johnston Jun 30 '15 at 20:14
  • It seems I have some misunderstanding. I'm using Qt and with it I can spawn `detached` processes that continue to run after parent exit. Also I can create `child` processes which get killed when parent exits. And I thought the same applies to native programming. – nikitablack Jul 01 '15 at 07:32
  • Your question is confusing. However your comments to my deleted answer make it clear that you want the child's life to be tied to its parent. I suggest you edit the question to make it clear. – David Heffernan Jul 01 '15 at 07:49
  • Sorry for confusion. Edited. – nikitablack Jul 01 '15 at 08:36
  • Get the process handle and terminate it when the parent terminates. – David Heffernan Jul 01 '15 at 17:15
  • @DavidHeffernan But this will only work for normal exit. Anyway, my problem is: if I use **UAC/nonUAC** parent and **nonUAC** child with `CreateProcess` and jobs - everything good. The same if I use **UAC** parent and **UAC** child. The bad things only happen when I use **nonUAC** parent and **UAC** child. In this case I can't use `CreateProcess` anymore - only `ShellExecute` and jobs not work anymore. I couldn't find any official solution. – nikitablack Jul 02 '15 at 07:00

1 Answers1

3

You have the use the shell verb runas to force elevation. Which rules out CreateProcess. So you can do the following:

  1. Use ShellExecuteEx to create the child process.
  2. Arrange for ShellExecuteEx to return a process handle for the child.
  3. When the parent terminates, terminate the child.

If you want to use jobs to tie the processes lives together then you need to include the requiresAdministrator manifest option of the child. That way you can use CreateProcess and specify the process creation flags as you desire.

Now, you may wish not to have the child process manifested that way. If so then you can still get the job done with a call to CreateProcess. You need three processes:

  • Parent process, runs as standard user.
  • Launcher process, manifested to be elevated. Created by parent, with appropriate job flags, and passed arguments that specify how to launch child. Which it does with CreateProcess and placed in same job.
  • Child process. Not manifested to be elevated. But because it is launched by the elevated launcher it too is elevated.

The point here is that there are two ways to force elevation. Statically at compile time with a manifest. That allows you to use CreateProcess. Or dynamically with the runas shell verb. That forces ShellExecuteEx. You state that you are pushed to CreateProcess, and so that means the use of a manifest to force elevation.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thank you. Just to clarify the second part - with 3 processes - launcher process is intermediate and shouldn't be placed in job. But I have to create a job in parent process, pass it to launcher process and launcher will place the child process into this job after spawning, right? – nikitablack Jul 02 '15 at 08:11
  • You could do it that way. Or you could have all three processes in the job. I'm not sure that it matters that much. I don't see any downside in having them all in the same job. – David Heffernan Jul 02 '15 at 08:15
  • 1
    Well, If parent is normal process and child is elevated, then placing it in the job always fails. – nikitablack Jul 02 '15 at 08:30