LoRd_MuldeR
1st December 2010 22:27 UTC
UAC_AsUser_ExecShell and %INSTDIR
Hello.
I'm using the UAC plugin v0.2.2c in my installer and so far everything seems to work fine. However there is a problem with the UAC_AsUser_ExecShell macro, which I'd like to use to launch the app after install. Unfortunately it doesn't work as expected, because obviously the "outer" installer still has the default install path in its $INSTDIR rather than the install path chosen by the user (I found out that the execution fails because a wrong path is used via ProcessMonitor, by the way).
My current workaround is as follows:
Function .onInstSuccess
!insertmacro UAC_AsUser_Call Function LaunchApplication ${UAC_SYNCINSTDIR}
FunctionEnd
Function LaunchApplication
ExecShell "explore" "$INSTDIR"
Exec '"$INSTDIR\Program.exe"'
FunctionEnd
Is there a more simple way to do this, e.g. by using UAC_AsUser_ExecShell macro ???
Thanks in advance!
(BTW: Is there a docu on UAC v0.2.2 anywhere? The Wiki page seems to be outdated)
Anders
1st December 2010 23:44 UTC
I'm guessing the UAC_AsUser_ExecShell macro is missing the ${UAC_SYNCINSTDIR} flag. And not there is no real documentation for 0.2 (I did not write most of the current page on the wiki either, but hey, it's a wiki, anyone can edit)
LoRd_MuldeR
2nd December 2010 15:00 UTC
Before I can (or should) edit the Wiki, I need to understand first ;)
Could you please tell me how to apply the ${UAC_SYNCINSTDIR} flag to the "UAC_AsUser_ExecShell" macro? To which of its parameters the flag has to go?
Regards,
MuldeR.
MSG
2nd December 2010 17:56 UTC
If you look in UAC.nsh, you'll see that the UAC_AsUser_ExecShell macro calls UAC_AsUser_Call using UAC_SYNCREGISTERS and UAC_SYNCOUTDIR, but not UAC_SYNCINSTDIR. You could try adding it yourself, or you can use a macro such as this:
!macro _SyncVariable _variable
!define Lprefix L${__LINE__}
push $R0
goto _SyncVariableInner${Lprefix}
_SyncVariableOuter${Lprefix}:
StrCpy $R0 ${_variable}
return
_SyncVariableInner${Lprefix}:
!insertmacro UAC_AsUser_Call Label _SyncVariableOuter${Lprefix} ${UAC_SYNCREGISTERS}
StrCpy ${_variable} $R0
!undef Lprefix
pop $R0
!macroend
!define SyncVariable `!insertmacro _SyncVariable`
And then:
${SyncVariable} $INSTDIR
(But of course this macro synchronizes from outer to inner, you'll probably want the reverse. Modifying the code is left as an exercise to the reader.)
LoRd_MuldeR
2nd December 2010 20:20 UTC
Originally posted by MSG
If you look in UAC.nsh, you'll see that the UAC_AsUser_ExecShell macro calls UAC_AsUser_Call using UAC_SYNCREGISTERS and UAC_SYNCOUTDIR, but not UAC_SYNCINSTDIR.
May I suggest to add it then?
I think it's quite common to call UAC_AsUser_ExecShell for launching the installed application from the
actual install directory. And in this situation the programmer would expect $INSTDIR to be synced. I can hardly think of a situation where you don't want it synced...
Anders
2nd December 2010 20:31 UTC
it's on my todo list
LoRd_MuldeR
2nd December 2010 20:38 UTC
Originally posted by Anders
it's on my todo list
Great :)
What do you think about adding UAC_AsUser_Exec and UAC_AsUser_ExecWait macros?
Anders
2nd December 2010 20:48 UTC
There is nothing stopping you from creating any kind of *Exec* helper macro yourself. But, my take on this is; CreateProcess is almost useless since windows could decide for any reason that your app requires elevation (Compat shim, installer detection etc) so you should stick with ShellExecute