Archive: ShellExecAsUser plugin


ShellExecAsUser plugin
I've created a new ShellExecAsUser plugin:
http://nsis.sourceforge.net/ShellExecAsUser_plug-in
It allows to execute the specified program in non-admin context, i.e. it is intended for installers that run with admin rights but need to execute something in non-admin context.
It uses desktop COM interface to execute process, so that process is launched by explorer (http://brandonlive.com/2008/04/27/ge...ou-part-2-how/).
Any comments are welcome.


Sound like something that can pretty useful :cool:

Two questions:
* What operating systems does it work with? Any "fall back" mode for WinXP and Win2k?
* Can you please compile a Unicode version of that plug-in?

(Sorry, did not have time to examine your code yet)

Regards,
MuldeR.


* What operating systems does it work with? Any "fall back" mode for WinXP and Win2k?
It should work starting from Win2k. On WinXP, Win2k (or if UAC is disabled) the plugin will do the launch using ShellExecute.

* Can you please compile a Unicode version of that plug-in?
Ok I'll do.

Thank you!


I have adopted your ExecShellAsUser method into my StdUtils plug-in:
http://pastie.org/private/b9cymlmclyuo6b1f4kcmfg

(ANSI and Unicode builds attached)


So, what, does this do what the UAC plugin was also designed to do, but without two installer instances?


Originally posted by MSG
So, what, does this do what the UAC plugin was also designed to do, but without two installer instances?
Yup. It generates a non-elevated process right from the elevated installer instance.

Seems to work for me on Windows 7 (x64). I don't have any other UAC-enabled test platforms.

On Windows XP and earlier it simply falls back to the normal ShellExecute()...

I have adopted your ExecShellAsUser method into my StdUtils plug-in:
Ok but note that I used another thread for desktop COM calls. Otherwise I (sometimes) got RPC_E_CANTCALLOUT_ININPUTSYNCCALL error, which is solved if you do it on another thread.

Originally posted by installer32
Ok but note that I used another thread for desktop COM calls. Otherwise I (sometimes) got RPC_E_CANTCALLOUT_ININPUTSYNCCALL error, which is solved if you do it on another thread.
Thanks for the hint!

(I already noticed that CoInitializeEx() fails, because, I think, COM already is initialized with other parameters for the calling thread. So I switched back to CoInitialize() again. But I will implement your suggestion now)

[UPDATE] Done. New version is attached. [/UPDATE]

Very cool! I use the UAC plugin for double install mode all-through, for which case I guess it is more convenient to have two instances. But this is a very cool alternative, and a lot simpler to use!


Small update:
http://nsis.sourceforge.net/StdUtils...xecShellAsUser


Sorry, here are some more fixes:


This COM hack is problematic and/or broken when:

A)
Explorer is not running

B)
Explorer is elevated (Rare, but some people do it)

C)
Desktop user is not the correct parent:
User A is logged on,
runs setup as non-admin user B with runas.exe,
setup is elevated with user C;
The correct user is B, not A.


In case (A) it will fall back to the normal ShellExecute(). Not ideal, but well...

I'm not sure what will happen in case (B) or how to reproduce this, but I guess in that case we will either fail to get the COM interface and thus fall back to the normal ShellExecute(), or we will simply create an elevated instance.

Again not ideal, but if you run your Explorer in an elevated way, then problems are preprogrammed anyway :rolleyes:

(And in case (C) it may depend on the situation/purpose whether user A or B is the "correct" one)


Anders
You are right and I'll add your remarks to plugin description, though I think it's quite uncommon and as such these limitations are acceptable to many people.


I have updated my StdUtils plug-in to use the "new" plug-in API, i.e. get rid of explicit unload.

Furthermore I added a version of ExecShell with wait capability as well as some more convenience functions.

New version here:
http://nsis.sourceforge.net/StdUtils_plug-in

(BTW: Could some mod please delete the obsolete versions attached to my previous posts?)


In case somebody is interested, I just uploaded a new version of my StdUtils plug-in:
http://nsis.sourceforge.net/StdUtils_plug-in


Originally posted by LoRd_MuldeR
In case somebody is interested, I just uploaded a new version of my StdUtils plug-in:
http://nsis.sourceforge.net/StdUtils_plug-in
I've just uploaded yet another update, which fixes a potential crash related to CoUninitialize() and certain certain Shell Extensions. In my case it was Tortoise GIT. Put simply, CoUninitialize() might still crash, even if all COM interfaces were released properly before. Happens if there are outstanding messages. It turns out we must dispatch all pending messages explicitly before calling CoUninitialize().

As this might be relevant for all NSIS plug-in's that deal with COM interfaces (and the Shell), you might want to have a look here:
http://stackoverflow.com/questions/1...itialize-crash