Archive: Vista - UAC - SetShellVarContext


Vista - UAC - SetShellVarContext
Guys would very much like assistance on my installation issue. When installing as a Standard User on Vista I am naturally prompted for Admin credentials. I provide the admin password for a user in the Admins group and am granted permission to proceed. Fine. When I install with the SetShellVarContext all, all of my user data files and shortcuts are placed under All Users. I can start my application but it crashes because the standard user does not have write permissions to the All Users documents directory where my demo data files are located. When I change the SetShellVarContext function to SetShellVarContext current, the data directories and shortcuts are placed under the Admin whose password I used to proceed with the install. I can't even locate a shortcut to install the application. I thought the UAC was designed to prevent this from happening.

While I could use SetShellVarContext all to get the shortcuts to show on the desktop and then rewrite my program to create data directories and files upon starting up, I am hoping to I can avoid all of that work. Using SetShellVarContext all seems like such a hack anyway if I really just want the current user to access their own data. If you could give me some guidance on how I can solve this problem I would be very appreciative. Thank you very much.

My install environment is,

NSIS 2.34
UAC Version 0.7c (Date: 20080218 )


Sincerely,


John Coffey


[/B]


" I thought the UAC was designed to prevent this from happening" this is by design, thats how UAC (Vista) works.

The UAC plugin on the other hand was designed to get around this, but not by using SetShellVarContext

try something like:

!include UAC.nsh
Function DoSomethingForUser
CreateDirectory "$desktop\foo"
FunctionEnd

Section
${UAC.CallFunctionAsUser} DoSomethingForUser
SectionEnd

and you should get the latest version of the uac plugin ( v0.0.8)

Originally posted by jpcoffey
Using SetShellVarContext all seems like such a hack anyway if I really just want the current user to access their own data.
You are really mixing two things, if you have RequestExecutionLevel admin, you should really only use SetShellVarContext all because you are doing a all users install, and that means you cannot create files for use by just the current user. It has been like this for all NT systems, its just that nobody seems to care, but as you have noticed, Vista changed that

Anders, thank you very much for your timely response. I took your suggestions and was elated to see my application start without mishap. Moreover, the applications started from the installer with the checkbox checked. Thank you!

Sadly, not all is well. While my app ran fine, there were no shortcuts on the desktop for this user. There were no shortcuts on the Start menu either! To make matters even more peculiar, the data directories were still in the My Documents folder of the Adminstrator whose password I used to authorize the install.

The only way I can imagine this happening is that the ${UAC.CallFunctionAsUser} does not pass the execution level to subroutines. Is this in fact the case? All of my user related functions are called using the "CallFunctionAsUser" however, the subroutines within those functions simply use the "Call [functionname]" syntax. DoI need to use CallFunctionAsUser for every single function call? Please advise.

Thank you again for allowing me to see that there is light at the end of the tunnel. Between reading all about the UAC on the MS website and on the NSIS site, I have probably been working this for three to four weeks. I should have asked for help sooner! Thank you!

Sincerely,

John P. Coffey


Anders, I rewrote my script using CallFunctionAsUser for every function to include subroutines and things did not change. BTW, when I installed my program on WindowsXP as a Standard User the install went perfectly. The shortcuts were created on the desktop and the StartMenu, so I then installed it on Vista which is when the problems started surfacing. I am at a loss as to what to do next. I will await your counsel before taking any more action. Thank you.

Sincerely,

John P. Coffey


use SetShellVarContext all before you create the shortcuts


something simple like

RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
!define APPNAME "UAC_AdminOnly"
Name "${APPNAME}"
OutFile "${APPNAME}.exe"
ShowInstDetails show

!include UAC.nsh

${UAC.AutoCodeUnload} ""


Function .OnInit
${UAC.I.Elevate.AdminOnly}
FunctionEnd



Function ExecCodeSegmentTest
messagebox mb_ok "$smprograms & $desktop"
FunctionEnd

Section "Info"
!insertmacro UAC.CallFunctionAsUser ExecCodeSegmentTest
SectionEnd

page InstFiles

will display the correct path for me, vista sp1, standard user elevated with a different admin user

Anders, thank you for providing the simplified script for Vista. I tried your script on my machine and it worked.

Therefore, I can only conclude that something somewhere is wrong with my script. I've started debugging my script by placing code from my script into yours to see if I can find that point in my code where the simple install script will crash. I can't compile because I keep getting the following error when I try to compile your simple script with just the headers and some variable declarations from my code pasted into it,

!insertmacro: end of _UAC.GenerateSimpleFunction
!insertmacro: _UAC.GenerateSimpleFunction
Function: ".OnInstSuccess"
Plugin Command: Unload
FunctionEnd
!insertmacro: end of _UAC.GenerateSimpleFunction
!error: UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_ABORT!
Error in macro UAC.AutoCodeUnload on macroline 7
Error in script "C:\MyApp\nsis_new_install\simple_test.nsi" on line 114 -- aborting creation process

The lines above are from the preview window in HM NIS Edit. I copied the last few lines. What is odd is you are not calling the MUI_CUSTOMFUNCTION_ABORT in the simple script you provided. Why am I all of a sudden getting a compile error for failing to call this function? I can see you made the call in the UAC_RealWorldFullyLoadedDualMode, but why is it being asked of me just because I pasted in some headers from my own script?

I'm beginning to think that some of plug-ins and includes are interfering with UAC. I am using MUI.nsh, Library.nsh, nsProcess.nsh, FileAssoc.nsh, FileFunc.nsh, XML.nsh, Sections.nsh, System.nsh, LogicLib.nsh, WinVer.nsh and their respective plug-ins. I am willing to give UAC priority if this will solve the problem, but I am not even sure if any priority can be given. Am I just barking up the wrong tree? As always, thanks for your feedback.

Sincerely,


John Coffey


yes, there is a problem with MUI, they both want to use the same function.

you need to call UAC::Unload in .OnInstFailed, .onUserAbort and .OnInstSuccess but MUI takes over those functions

so, add:


!define MUI_CUSTOMFUNCTION_ABORT myAbort
Function myAbort
${UAC.Unload}
FunctionEnd


Anders, I got it. I finally got my application to install on Vista as a Standard User with all of the shortcuts in the Start Menu, on the Desktop and the checkbox to start my application. I am elated and am very grateful for your guidance. Thank you for your help.

More importantly, thank you for authoring UAC.dll. It is a fantastic control that circumvents the encumbrances of Vista beautifully.

For the benefit of any others who may be trying to figure out why their installation isn't working, I will share my numb-nut mistake which cost me so much time/energy. My uninstall routines are separated from my installation routines by several lines of "=" signs. It is easy to convince yourself after a while that they are completely different areas and have nothing to do with each other. That is why I overlooked the RequestExecutionLevel admin in the uninstall area of my very long script. Since the RequestExecutionLevel cannot be placed in a function or a section, it naturally was in the body of the entire script. Therefore, when I ran my install with RequestExecutionLevel user and was operating as the admin I was confused beyond description. My advice, if you are not going to use the UAC to uninstall your application and are going to just use generic admin privileges just leave RequestExecutionLevel out altogether. NSIS is automatically recognized as an install/uninstall system and does not need it. I hope this saves you days and days and days of pain.

Sincerely,

John Coffey


that is not really use, you should always use RequestExecutionLevel, either with user or admin, otherwise your installer might (could be turned off in the security policy) be detected as a legacy installer, and you would have to deal with folder redirection and things


Anders, thanks for your feedback. Where would I put the RequestExecutionLevel statement? As evidenced by the following error messages it cannot be placed in either a Section or a Function,

Error: command RequestExecutionLevel not valid in Section

Error: command RequestExecutionLevel not valid in Function

Therefore, it has to go in the body of the script. I read somewhere that I should have it in my script as well which is probably why it was there. I overlooked its impact on the install script, because I deluded myself into believing that my uninstall routines were completely separate. So, I can only conclude from your message that if we use the UAC.dll in the install we should use the UAC.dll in the uninstall as well. That way we could install and uninstall and explicitly make a call to RequestExecutionLevel user. Is that correct?

Sincerely,

John Coffey


yeah, but it is a bit of a problem.

to use the UAC plugin, you have to have RequestExecutionLevel user, but in the uninstaller, you really just want RequestExecutionLevel admin, but that is not possible unless you have a seperate script that generates the uninstaller. There have been a couple of forum threads about this already...