views:

1224

answers:

2

Hi,

I'm using the ShellExecuteEx function in a C++ program to launch an Uninstall.lnk file. In my program, I'd like to wait for the uninstaller to finish. My first attempt was to set the SEE_MASK_NOCLOSEPROCESS flag in the SHELLEXECUTEINFO structure and then call WaitForSingleObject on the hProcess handle available in the SHELLEXECUTEINFO structure passed to ShellExecuteEx, but that still seemed to return way too early.

My current suspicion is that this is because the process launched by ShellExecuteEx (does it launch a new shell?) creates new child processes, but doesn't wait for them. So I'm trying to create a "wait for my child process and all the children it launches" function. To do so, I'm trying to use job objects.

I created a job object using CreateJobObject, assigned the process handle returned by ShellExecuteEx to the job and then attempted to wait for the job object. Unfortunately assigning the process to the job failed, and I think this is due to insufficient access rights.

Does anybody know how to set the PROCESS_SET_QUOTA and PROCESS_TERMINATE access rights (which are required for AssignProcessToJobObject to succeed, according to the MSDN) on a process handle, or another way to wait for the process launched by ShellExecuteEx to finish?

UPDATE: I should point out that I'm also launching other applications, not just Uninstall.lnk. One of them is e.g. a ClickOnce application, which is effectively a simple XML file with the file extension .application.

+2  A: 

Vista uses job objects for launching links. Therefor the process you try to assign to another job object might already be assigned.

See: this question

EFraim
Good point. Indeed, it seems as if sometimes (depending on the kind of file I launch via `ShellExecuteEx`), the launched process is already part of a job object. Unfortunately it's not possible to break this association. :-/
Frerich Raabe
Good point. One of the reasons to use ShellExecuteEx is to hand of a whole bunch of responsibilities to the Shell. If you want more precise control, such as Job control, use CreateProcess.
MSalters
Accepting this answer since it's the most useful one.
Frerich Raabe
+1  A: 

Why not to execute target file instead of openning Uninstall.lnk? You could use IShellLink to get shortcut target. Then you'll be able to execute target file via ShellExecuteEx using SEE_MASK_NOCLOSEPROCESS flag.

Kirill V. Lyadvinsky
If target process spawns another process (like msiexec.exe) and dies, this won't help.
Paul
Then you should to execute `msiexec.exe` or even better to use installer API.
Kirill V. Lyadvinsky
I'm sorry for the imprecision; I'm also launching other types of files, not just .lnk files. I also launch ordinary .exe files as well as ClickOnce applications (.application files).
Frerich Raabe