Skip to content
⌘ NSIS Forum Archive

ExecWait fails if RequestExecutionLevel user and new process requires elevation

7 posts

alexmitev#

ExecWait fails if RequestExecutionLevel user and new process requires elevation

Hello,
I have an issue using Exec/Exec wait from a script that sets RequestExecutionLevel user and new process requires elevation. Sample code:
RequestExecutionLevel user
ExecWait '"D:\Programs\nsis-3.01-setup.exe"' 
I tried the CreateProcess code suggested here and it returned error code ERROR_ELEVATION_REQUIRED. I digged a little more and found this article which suggests all CreateProcess() calls should be replaced by ShellExecute(). I searched the NSIS code, seems like the myCreateProcess() function has to use ShellExecute() instead of CreateProcess() ...
Anders#
If you know you need elevation then it is much better to ask for it upfront.

If you insist on your current design you can use http://nsis.sourceforge.net/ShellExecWait
alexmitev#
Well, if I'm running third party application, there is no way of knowing if it will need elevation. Even if I'm running my own uninstaller, the elevation requirements might change between versions.
Yes, I saw this plugin, seems it has to be used every time instead of Exec/ExecWait, at least until NSIS core code changes, which I guess won't happen ever...
Anders#
Originally Posted by alexmitev View Post
... at least until NSIS core code changes, which I guess won't happen ever...
While I agree that NSIS really should have a ExecShellWait instruction there are a couple of reasons why it has not been added yet.

1) People are going to complain that it does not always wait and I'm the one that ends up having to explain why over and over again. (A selfish reason, I know)

2) It means we would switch from ShellExecute to ShellExecuteEx and ShellExecute in shell32.dll actually calls ShellExecuteEx with a flag that Microsoft refuses to document and this flag does effect how certain things are executed! If we use the flag then we are relying on undocumented stuff that could break in the future. If we don't use the flag we break backward compatibility.
alexmitev#
Thank you for your reply, Anders.

I think ExecWait now calls CreateProcess + WaitForSingleObject, or I am wrong?
We don't have to change it.
If we add the new instruction ExecShellWait, it would call ShellExecuteEx(SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NOASYNC) + WaitForSingleObject(INFINITE), like the plugin does.
I am using this approach now in my code and I think it always waits, as long as it's called with the SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NOASYNC flags and it's called with the 'open' verb on an executable file.
I guess the reason for using ShellExecute() is that ShellExecuteEx() is supported on XP and above. I guess ExecShellWait can just fallback to ExecWait on systems older than XP, which don't have UAC anyway.
alexmitev#
Originally Posted by Anders View Post
My point was that ExecShell would change and call ShellExecuteEx as well.
I don't see a reason to change the ExecShell implementation. You said there is going to be a new function ExecShellWait. I don't think it will call ExecShell or rely on its implementation.