Archive: UAC v0.0.11d plug-in - several questions


UAC v0.0.11d plug-in - several questions
  Hi,

I am using the UAC v0.0.11d plugin (Unicode dll). After reading and trying out the Readme, Wiki pages and forum posts, I still have some questions.

I am running Windows 7 32Bit. When the UAC is enabled all works fine. But when I switch off the UAC the plug-in dialog for the run as pops up. It allows to use the current (Standard) user by default. This is not wanted in my case. So I tried to put the file UAC.LNG (example taken from the Readme file) in NSIS Plugin dir and to set HideCurrUserOpt=1. But with no result. Did I miss something?
I don't want the Current User option in any Windows version.
(Found this thread here http://forums.shoutcast.com/showthread.php?t=291307 but didn't help me)

And as far as I understood the whole concept, UAC is only available/ supported in Vista and Win 7. Anything to take care of for all other versions to make sure that the installer runs with Admin privileges?

Next thing I would like to know if there is any way other than the one described in this thread http://forums.winamp.com/showpost.ph...93&postcount=8 to pass variables and/ or stack values from the outer to the inner process? The other way round there is UAC::StackPush.

On the UAC Wiki page under Important Notes (http://nsis.sourceforge.net/UAC_plug-in#Important_Notes) is written:

3. When a standard or limited user supplies administrator information into the Run As dialog, you may experience permissions trouble with any extracted file. For example, if a Windows 2000 standard user supplies administrator info into the Run As dialog, and the NSIS installer extracts an .exe file, then trying to call that .exe through an Exec can fail. If this is a problem, you will want to use the AccessControl plug-in.
Does this belong to all Windows versions?
Because during installation my installer extracts/ copies a "vcredist_x86.exe" file to the Instdir which is then being executed by ExecWait and after extraction it is deleted.
So do I have to use the AccessControl plug-in too? Or just in case the initial user isn't a member of the Admin group?
BTW: Would it make sense to "bypass" the whole UAC elevation thing if version (WinVer) is one prior to Vista and/ or (UserInfo) reports that the member has already Admin privileges? If so, how to do it best?

Maybe it will be helpful if I describe in short what the installer needs to do:
The installer needs to be run by an Admin process token to install the program to $PROGRAMFILES and write entries to HKLM. But it also needs to check for existance of some files in the users (the initial user - not the one who granted the privileges) $APPDATA dir and read + write to HKCU.

Many thanks for your help!

Gunther

PS: And sorry for opening a new thread, but IMHO it makes more sense for future users also using UAC plugin to have it all in one post. Especially because the search function of the forum denies some of the logical keywords as being to long and with other ones it finds no results even if there are respective posts. These you can only find with the help of Google & Co.

Originally posted by Netsurfer24
And as far as I understood the whole concept, UAC is only available/ supported in Vista and Win 7. Anything to take care of for all other versions to make sure that the installer runs with Admin privileges?
Yes, UAC exists since Windows Vista. But the UAC plugin works on all recent windows versions. Technically, it doesn't have anything to do with User Account Control, it just allows you to run two instances of your installer (userlevel outer and adminlevel inner instance). It's only called the UAC plugin because that's what it was originally created for.

But if you don't want dual-mode installations on WinXP etc, simply don't call the UAC plugin on those OSes and instead throw an error 'Needs admin' if the installer is run as user.


And as for this issue:
Originally posted by Netsurfer24
It allows to use the current (Standard) user by default.
You need to manually check what user the installer was elevated to, and if it's not an admin level account you need to quit the inner instance and force the user to elevate once more. See the dualmode example scripts for details.



Originally posted by Netsurfer24
Next thing I would like to know if there is any way other than the one described in this thread http://forums.winamp.com/showpost.ph...93&postcount=8 to pass variables and/ or stack values from the outer to the inner process? The other way round there is UAC::StackPush.
I use a very simple macro to synchronize variables and/or registers between instances. I don't have it at hand atm, I can post it some time tomorrow if you want.

Originally posted by Netsurfer24
On the UAC Wiki page under Important Notes (http://nsis.sourceforge.net/UAC_plug-in#Important_Notes) is written:
3. When a standard or limited user supplies administrator information into the Run As dialog, you may experience permissions trouble with any extracted file. For example, if a Windows 2000 standard user supplies administrator info into the Run As dialog, and the NSIS installer extracts an .exe file, then trying to call that .exe through an Exec can fail. If this is a problem, you will want to use the AccessControl plug-in.
Does this belong to all Windows versions?
Because during installation my installer extracts/ copies a "vcredist_x86.exe" file to the Instdir which is then being executed by ExecWait and after extraction it is deleted.
So do I have to use the AccessControl plug-in too? Or just in case the initial user isn't a member of the Admin group?
Yes, or extract the exe file from the outer (userlevel) instance. You won't have any privilege problems then.


Originally posted by Netsurfer24
The installer needs to be run by an Admin process token to install the program to $PROGRAMFILES and write entries to HKLM. But it also needs to check for existance of some files in the users (the initial user - not the one who granted the privileges) $APPDATA dir and read + write to HKCU.
If an admin process is starting the installer, you cannot de-elevate to userlevel. You need to call the installer from userlevel.



Edit: By the way, I really suggest you use the latest 'experimental' version. It's much better.

switched to version UAC v0.2.2b - 20100103
  Hi MSG!

Edit: By the way, I really suggest you use the latest 'experimental' version. It's much better.
I would do this, but as there is no documentation for the new version and I do not fully understand it (e.g. what the ${UAC_SYNCREGISTERS} exactly does) yet.
But anyway - switched to the new version.

But if you don't want dual-mode installations on WinXP etc, simply don't call the UAC plugin on those OSes and instead throw an error 'Needs admin' if the installer is run as user.
No, I want the possibility to start the installer as a Standard user but make sure it runs with Admin privileges on every Windows version.

And as for this issue:
You need to manually check what user the installer was elevated to, and if it's not an admin level account you need to quit the inner instance and force the user to elevate once more. See the dualmode example scripts for details.
OK, should be no problem ...

I use a very simple macro to synchronize variables and/or registers between instances. I don't have it at hand atm, I can post it some time tomorrow if you want.
That would be great ...! :up:
I need a possibility to "transfer" data from the inner to the outer process and vice versa.

Yes, or extract the exe file from the outer (userlevel) instance. You won't have any privilege problems then.
Hehe ..., of course - sometimes it is quite that simple (that one just not thought about it).

If an admin process is starting the installer, you cannot de-elevate to userlevel. You need to call the installer from userlevel.
Yes, that's clear. If the user who started the installer is already an Admin then there is no problem and $APPDATA and HKCU belong to the user. But the installer also should be able to be started by a Standard user. And in this case I need to switch to the outer process for being able to get the values for the initial user.

Thanks so far!

Gunther

Hi!

I now use the following code in .onInit function:

StrCpy $USERS_APPDATA $APPDATA


uac_tryagain:
!insertmacro UAC_RunElevated
>...

${If} ${
UAC_IsInnerInstance}
!insertmacro UAC_AsUser_GetGlobalVar $USERS_APPDATA
>${EndIf}
By doing so I get the (initial) users $APPDATA value in the variable $USERS_APPDATA. If there is no inner process (initial user is already Admin) then $USERS_APPDATA == $APPDATA. That's what I need.

But once again back to the question
So do I have to use the AccessControl plug-in too? Or just in case the initial user isn't a member of the Admin group?
and MSG's answer
Yes, or extract the exe file from the outer (userlevel) instance. You won't have any privilege problems then.
As I do so and run the extraction from the outer (userlevel) instance, wouldn't I run then into trouble (with any privileges)? Because the files are installed in $PROGRAMFILES as an installation for ALL users.
So I guess I have to use the AccessControl plug-in anyway, haven't I?

And there is still the question if it is possible to disable the Current User radio button in the RunAs dialog?
I guess I need the handle of the dialog and the ID of the radio button?

And of course I am still interested in MSG's promised way to exchange data between the inner and outer process.

Thanks,

Gunther

Originally posted by Netsurfer24
No, I want the possibility to start the installer as a Standard user but make sure it runs with Admin privileges on every Windows version.
This is a contradiction. An installer started as a user will have user access privileges. An installer started as an admin will have admin access privileges. You cannot start as a user and have admin privileges.

Originally posted by Netsurfer24
I need a possibility to "transfer" data from the inner to the outer process and vice versa.
http://nsis.pastebin.com/eM9MDUYL
The SyncVariable macro will make sure that variables that were set before elevation occured, are copied out of the outer (user level) instance into the inner instance. You can use it in your .onInit function, like this:
 ${If} ${UAC_IsInnerInstance}

${
SyncVariable} $Variable1
${SyncVariable} $Variable2
${EndIf}
The SyncSection macro does the same thing for section flags. (I don't think I ever tested if this was already automatically done by the UAC plugin, perhaps the macro isn't necessary at all.)

To get variable values INTO the outer (user level) instance, you can make a similar macro, or just use registers, because the UAC plugin can synchronize registers automatically:
  StrCpy$8 $STARTMENUSHORTCUTS

StrCpy$9 $DESKTOPSHORTCUT
!insertmacro UAC_AsUser_Call function InstallShortcuts ${UAC_SYNCREGISTERS}
(...and then in the InstallShortcuts function I use $8 and $9 instead of the actual variables, of course.)

Originally posted by Netsurfer24
The installer also should be able to be started by a Standard user. And in this case I need to switch to the outer process for being able to get the values for the initial user.
The SyncVariable macro won't work here because you don't want to overwrite the inner instance's $APPDATA variable. Just use the registers trick:
Function GetAppData

setshellvarcontext current
StrCpy$9 $APPDATA
FunctionEnd

!insertmacro UAC_AsUser_Call function GetAppData ${UAC_SYNCREGISTERS}
SetOutPath $9
>

Originally posted by Netsurfer24
As I run the extraction from the outer (userlevel) instance, wouldn't I run then into trouble (with any privileges)? Because the files are installed in $PROGRAMFILES as an installation for ALL users.
So I guess I have to use the AccessControl plug-in anyway, haven't I?
Well... That depends on how you look at it. From a technical standpoint, if you want a normal user to have write access to $INSTDIR, then yes, you need to give all users write access using the AccessControl plugin. But from a software design standpoint, doing this is VERY, VERY bad practice:
If a regular user has write access to a subfolder of Program Files, that user might do something stupid that causes malware to install itself in that folder. Then an admin might think "Program Files is a protected directory, so I don't have to worry about users putting malware in this directory," and he would run any executable in Program Files without thinking twice about it. And voila, you have your malware executed at admin level and the system is compromised.

It's up to you to decide whether you want to take that risk or not, but keep in mind that your end-users are usually NOT very smart, so following proper procedure is very important if you're creating something for the grand public.


Originally posted by Netsurfer24
And there is still the question if it is possible to disable the Current User radio button in the RunAs dialog?
I guess I need the handle of the dialog and the ID of the radio button?
I'm not sure. Maybe. Anders would know. But I don't see why you'd want to go through all that trouble. You need to check if elevation was performed properly, anyway (UserInfo plugin in ${If} ${UAC_IsInnerInstance}). Just throw a MessageBox error if the user 'elevated' to a normal user.


***93;

>DisableCurrUserOpt=1
>

onInit

Initpluginsdir
File"/oname=$pluginsdir\uac.lng" uac.lng #or just WriteIniStr
>...
But, this will not always work since there are 3 different Run As dialogs! (Windows 2000, XP+2003 and the custom UAC plugin dialog used on NT6 when UAC is off) The uac.lng file only works for the custom dialog (It's only purpose is to deal with broken runas on Vista when UAC is off)
Even if I hooked the native dialog on NT5 and disabled the current user radio button, the user could enter the name/password of a standard user in the text fields.

The bottom line is, you have to deal with the fact that a non admin user can be selected in the run as dialog. (You don't HAVE to use the userinfo plugin, after UAC_RunElevated returns, $3 is != 0 if the user is admin IIRC)

@Anders

Originally posted by Anders
***91;MyRunAsCfg***93;

>DisableCurrUserOpt=1
>

onInit

Initpluginsdir
File"/oname=$pluginsdir\uac.lng" uac.lng #or just WriteIniStr
>...
I always get the following error:
InitPluginsDir
File: "uac.lng" -> no files found.
Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |
/oname=outfile one_file_only)
Error in script "F:/NSIS-Build_01/_CPack_Packages/win32/NSIS/project.nsi" on line 1106 -- aborting creation process
Is there anything else I have to do or take care off?

But, this will not always work since there are 3 different Run As dialogs! (Windows 2000, XP+2003 and the custom UAC plugin dialog used on NT6 when UAC is off) The uac.lng file only works for the custom dialog (It's only purpose is to deal with broken runas on Vista when UAC is off)
Even if I hooked the native dialog on NT5 and disabled the current user radio button, the user could enter the name/password of a standard user in the text fields.

The bottom line is, you have to deal with the fact that a non admin user can be selected in the run as dialog. (You don't HAVE to use the userinfo plugin, after UAC_RunElevated returns, $3 is != 0 if the user is admin IIRC)
Yes, I know. And I am using the same code as in the UAC_AdminOnly.nsi! So it is more or less for usability reasons to not irritate the unexperienced user.

Feature Request: Using WinVer.nsh it should be relatively easy to get it working for all cases.

Thanks,

Gunther

Originally Posted by Netsurfer24 Is there anything else I have to do or take care off?
You need to create the file yourself, or use the ini functions


Originally Posted by Netsurfer24 Yes, I know. And I am using the same code as in the UAC_AdminOnly.nsi! So it is more or less for usability reasons to not irritate the unexperienced user.

Feature Request: Using WinVer.nsh it should be relatively easy to get it working for all cases.
What does WinVer have to do with anything? The run as dialog on 2000/XP/2003 is provided by windows and not by the plugin

Originally posted by Anders
You need to create the file yourself, or use the ini functions
I tried both variants without success.
If I create the file myself where do I have to locate it?
And if I just want to use the INI functions what's the file name and location?
It is not located in the $PLUGINSDIR. There is only the UAC.dll (among the other DLL files) while the installer is running.


What does WinVer have to do with anything? The run as dialog on 2000/XP/2003 is provided by windows and not by the plugin
I understood your writing
But, this will not always work since there are 3 different Run As dialogs! (Windows 2000, XP+2003 and the custom UAC plugin dialog used on NT6 when UAC is off) The uac.lng file only works for the custom dialog
as if the Windows version has something to do with which dialog will be shown. And as it is always shown when the installer is already running, it should be possible to e.g. disable the Current User radio button in every Run As dialog. That's what I thought at least.
But maybe I got it all wrong ..., and it is not that important anyway.

Thanks

Gunther

Hi MSG!

Originally posted by MSG
This is a contradiction. An installer started as a user will have user access privileges. An installer started as an admin will have admin access privileges. You cannot start as a user and have admin privileges.
This seems to be a misunderstanding. If the installer is started with admin access privileges everything is fine => no further things to do.
But if it is started without (by a Standard User) which should be possible then the UAC plug-in comes to play as it then starts a second process which definitely needs admin access privileges.

Well... That depends on how you look at it. From a technical standpoint, if you want a normal user to have write access to $INSTDIR, then yes, you need to give all users write access using the AccessControl plugin. But from a software design standpoint, doing this is VERY, VERY bad practice:
If a regular user has write access to a subfolder of Program Files, that user might do something stupid that causes malware to install itself in that folder. Then an admin might think "Program Files is a protected directory, so I don't have to worry about users putting malware in this directory," and he would run any executable in Program Files without thinking twice about it. And voila, you have your malware executed at admin level and the system is compromised.

It's up to you to decide whether you want to take that risk or not, but keep in mind that your end-users are usually NOT very smart, so following proper procedure is very important if you're creating something for the grand public.
Thanks for the explanation. And as written before my installer just copies a self-extracting archive file (vcredist_x86.exe) which contains 5 DLL files. After copying it to a temp install dir it is called by ExecWait to extract those 5 files and after extraction it is deleted. All this is (normally) done by the admin token process (inner process if the installer runs elevated). A "normal" user does not need write access to the programs install dir. But point three on the UAC plug-in page irritated me as it says:
When a standard or limited user supplies administrator information into the Run As dialog, you may experience permissions trouble with any extracted file. For example, if a Windows 2000 standard user supplies administrator info into the Run As dialog, and the NSIS installer extracts an .exe file, then trying to call that .exe through an Exec can fail. If this is a problem, you will want to use the AccessControl plug-in.
And of course is the main program file which will be installed also an exe file which needs to be run by any user after installation.
So my question is: Will the above scenario (copy exe file and run it during installation) trigger this permissions trouble or not (if both are run by the user with the admin access privileges)?
Sorry for asking this question again but I think the note on the UAC plug-in page is very confusing at least to me.

Thanks

Gunther

The filename is $PLUGINSDIR\uac.lng but you have to create it on your own.

Yes, it is possible to disable it in all versions, but removing features from a standard windows dialog is not really something I want to do, so you are stuck with it only working on the dialog that I create, not the dialogs that are owned by windows.


Hi Anders!

Originally posted by Anders
The filename is $PLUGINSDIR\uac.lng but you have to create it on your own.
Just to get it right:
I first create a file by using
ClearErrors
FileOpen$0 $PLUGINSDIRuac.lng w
IfErrors done
FileClose $0
done:
and then use
WriteINIStr $PLUGINSDIRuac.lng MyRunAsCfg DisableCurrUserOpt=1 

>
to add the desired config option?
BTW: The backslashes are removed by the forums software.

Yes, it is possible to disable it in all versions, but removing features from a standard windows dialog is not really something I want to do, so you are stuck with it only working on the dialog that I create, not the dialogs that are owned by windows.
OK, no problem (as written before) - it is only a question of usability. ;)
Just my 2 cents ...
Poping up a dialog just in case that the actually logged-on user hasn't the needed permissions to go on and then offering the option to use the same user is far from being "logical". It is the same as if you would pop-up a messagebox with Yes + No button where the message says "... click Yes to continue" and everytime the user clicks on No the messagebox pop-up again. In such a case a messagebox with OK + Cancel button would be more logical.

Thanks

Gunther

There is no need to use FileOpen, just use the ini function directly (your syntax is wrong btw)

As far as the dialog goes, I don't seem to be able to make myself clear, I don't control the dialog or its content so stop bitching about it


Originally posted by Netsurfer24
Just my 2 cents ...
Poping up a dialog just in case that the actually logged-on user hasn't the needed permissions to go on and then offering the option to use the same user is far from being "logical".
I consider it rather obvious to warn the user that admin access is required, before you show the RunAs dialog. Otherwise they have no clue what they should do with it, or why they're getting it. But it's up to you how you design your UI, I guess.

Originally posted by Netsurfer24
If the installer is started with admin access privileges everything is fine => no further things to do.
But if it is started without (by a Standard User) which should be possible then the UAC plug-in comes to play as it then starts a second process which definitely needs admin access privileges.
And that is exactly why you need to verify that the inner instance was actually Run As an administrator user, and not some other regular user. That's what I've been telling you for the past two days.

Originally posted by Netsurfer24
Will the above scenario (copy exe file and run it during installation) trigger this permissions trouble or not (if both are run by the user with the admin access privileges)?
Sorry for asking this question again but I think the note on the UAC plug-in page is very confusing at least to me.
If an administrator process creates a directory and/or file, a user MIGHT not have write access to that folder/file. For example, when the admin process creates something in Program Files, which is a protected directory. That should be quite obvious. What part of it do you find so hard to understand? The note merely warns you to keep access privileges in mind, because the outer user process is not allowed to do as much as the inner admin process.

Originally posted by Netsurfer24
Just to get it right:
That seems about right. But why don't you just TRY it?

Hi Anders and MSG!

First of all let me say that I have the sense that we talk at cross purposes which may be caused by my inability to express myself in an understandable way. But as you may have noticed already English isn't my native language and so I also might misread some of the writings here in the forum, the Wiki and in the Readme files. Or they confuse me instead of making things clearer. So sorry for that.

Originally posted by MSG
I consider it rather obvious to warn the user that admin access is required, before you show the RunAs dialog. Otherwise they have no clue what they should do with it, or why they're getting it. But it's up to you how you design your UI, I guess.
You are right and I agree. But it wasn't that obvious to me as I thought the dialog is only shown if the currently logged-on user hasn't unsufficient rights. And in that case it is still illogical to me that the dialog offers the option to go on with the current user. But I understood that it is a Windows dialog and that it is beyond the scope of the installer. So if there is no way (don't hit me Anders) to modify the dialog from the installer script it seems to be the best solution to
... warn the user that admin access is required, before you show the RunAs dialog
Concerning
And that is exactly why you need to verify that the inner instance was actually Run As an administrator user, and not some other regular user. That's what I've been telling you for the past two days.
Yes, this is one the points where we talk at cross purposes. This is clear and I am doing so (from the beginning).

If an administrator process creates a directory and/or file, a user MIGHT not have write access to that folder/file. For example, when the admin process creates something in Program Files, which is a protected directory. That should be quite obvious. What part of it do you find so hard to understand? The note merely warns you to keep access privileges in mind, because the outer user process is not allowed to do as much as the inner admin process.
The note could easily be misread.
For example, if a Windows 2000 standard user supplies administrator info into the Run As dialog, and the NSIS installer extracts an .exe file, then trying to call that .exe through an Exec can fail.
First thing is clear: The installer runs elevated.
But then a clear statement which process (inner or outer) is meant is missing. And it could be interpreted as this occurs even if both operations are done by the inner (admin) process which is not the case.
So saying: "For example, if a Windows 2000 standard user supplies administrator info into the Run As dialog, and the NSIS installer inner process (with admin privileges) extracts an .exe file, then trying to call that .exe through the outer (user level) process (an UAC::Exec) can fail." would make it much clearer.
So in my case there should be no problem as I am doing all these operations from the inner process.

Originally posted by Anders
As far as the dialog goes, I don't seem to be able to make myself clear, I don't control the dialog or its content ...
This I didn't understand as you wrote in http://forums.winamp.com/showpost.ph...7&postcount=11
Yes, it is possible to disable it in all versions ...
So please forgive me when I was a little confused.

Same with the INI file for the Run As dialog.
The line in the Readme of the old version
If the plugin is built with FEAT_CUSTOMRUNASDLG_TRANSLATE (Enabled by default), you can extract a file named UAC.LNG to $pluginsdir.
led me to the wrong path. Saying "..., you can create a (an INI) file ..." would have made it clearer to me. But I got it now.

Even though these settings only take place when the Run As dialog created by the installer is shown which is only the case on Vista with UAC off, correct?
RunAs.cpp is only used if the user is non admin,running on Vista with UAC off (And it is only there since the built in RunAs seems to be broken)
Are my following conclusions correct?
It is assumed that the logged-on user has no Admin privileges.
- On Windows 2000, 2003 and XP the "normal" Windows Run As dialog is shown.
- On Windows Vista and Win 7 it depends on the UAC setting. It is only shown if UAC is disabled. Additionally on Vista the dialog created by the UAC plugin is shown (instead of the Windows one because it is broken).

If all of the above is correct then I'll leave the dialog as is (not worth the effort if there is no easy way to disable the Current user radio button).

Thanks again for your help and patience.

Gunther

Originally posted by Netsurfer24
Are my following conclusions correct?
It is assumed that the logged-on user has no Admin privileges.
- On Windows 2000, 2003 and XP the "normal" Windows Run As dialog is shown.
- On Windows Vista and Win 7 it depends on the UAC setting. It is only shown if UAC is disabled. Additionally on Vista the dialog created by the UAC plugin is shown (instead of the Windows one because it is broken).
Yes. With the added note that the win2k runas dialog is different from the XP+ runas dialog, as Anders pointed out.

Originally posted by Netsurfer24
If all of the above is correct then I'll leave the dialog as is (not worth the effort if there is no easy way to disable the Current user radio button).
...which is basically what I told you two days ago. Something I mentioned about "going through all that trouble".

Originally posted by MSG
Yes. With the added note that the win2k runas dialog is different from the XP+ runas dialog, as Anders pointed out.
OK - understood.

...which is basically what I told you two days ago. Something I mentioned about "going through all that trouble".
Yeah, you were right from the beginning. Took me some days to understand it. ;)

BTW:
On Vista and Win 7 with UAC enabled it is not necessary to show a messagebox to the user before the Run As dialog as it won't appear.

Using the new version of the UAC plug-in, is there a equivalent for Or any other way to determine if UAC is disabled (on Vista or Win 7)?
I can determine the Windows version by using WinVer.nsh.

Thanks

Gunther

GetElevationType was for help during debugging. There is no public UAC api in windows, so I removed SupportsUAC (You can check the EnableLUA registry value yourself)


New question/ problem with Uninstaller
  Hi, it's me again ....

Now that I have managed to set up all my needed functionality for the Installer I am now at the Uninstaller part. And immediately the problems start again ...!

Same as for the Installer I need to use the UAC plugin also for the Uninstaller to assure that it runs with Admin privileges.
So I wanted to "reuse" some of my code of the .onInit function in un.onInit.

This mostly works but I am getting an error saying:

Processed 1 file, writing output:
Adding plug-ins initializing function... Done!
Error: could not resolve label "_UAC_AUGOGR_OP$USERS_NAMEStrCpy$USERS_NAME_F" in function "un.onInit"
Error - aborting creation process
This comes from the lines:

}

!insertmacro UAC_AsUser_GetGlobalVar $USERS_NAME
>${EndIf}
The variable is set earlier in the function:

Call un.GetUserInfo

StrCpy $USERS_NAME $USERNAME
>
I do not understand at the moment why the code is not working (as the rest seems to work properly)?
Is it maybe a bug in the UAC_AsUser_GetGlobalVar macro so that it doesn't work for Uninstaller?

(Note that I am not asking for any other solution - I found already one by using MSG tip calling an extra function by UAC_AsUser_Call and the ${UAC_SYNCREGISTERS} option.)

Gunther

PS: I am using the newest version UAC v0.2.2c - 20100828 of the UAC plugin.

The AsUser stuff cannot really be used in the uninstaller.

(I can't remember if you are doing a dual mode install or not but...) My advice is to generate two uninstallers at compile time, one with requestexecutionlevel user and the other with admin. Then when you install, extract the correct one.

...And why the AsUser stuff cannot be used in the uninstaller? Well, with a uninstall registry entry in HKLM, Vista will auto-elevate so there is no way for me to get a outer instance. Sad but true.


Hi Anders!

Originally posted by Anders
The AsUser stuff cannot really be used in the uninstaller.

(I can't remember if you are doing a dual mode install or not but...)
No, I do not. As I always install the program for all users Admin privileges are required. And therefor the HKLM Regkey is used.

My advice is to generate two uninstallers at compile time, one with requestexecutionlevel user and the other with admin. Then when you install, extract the correct one.
Hmmm ..., if I got the previous right this won't be necessary - correct?
But anyway - how to do this?
My installer uses 'RequestExecutionLevel highest'. So how can I create an uninstaller with 'RequestExecutionLevel admin' (which would be sufficient for me)?

And is there a way to delete a certain directory from all users on a system?
Or to get the $APPDATA of all available users on the respective system?

...And why the AsUser stuff cannot be used in the uninstaller? Well, with a uninstall registry entry in HKLM, Vista will auto-elevate so there is no way for me to get a outer instance. Sad but true.
Ups! Do I run into trouble here ...?

I am on Windows 7 and with the UAC off the UAC plugin works as expected which means it creates an inner and outer process if the original user has no Admin privileges.

Do you mean this will fail on Vista?

Once again a little confused

Gunther

UAC off?


Originally posted by Anders
UAC off?
Yes, but of course it should also functioning with UAC on.

When it is off then the RunAs dialog is shown (see previous discussion in this thread here).

Meanwhile I found another thread here in the forum: http://forums.winamp.com/showthread....hreadid=280330

But it is still not clear to me ... :(

So it is problem that only occurs on Vista?
On Vista the UAC plugin isn't able to start a second process by '!insertmacro UAC_RunElevated'?

Gunther

Netsurfer, if you're not doing a dualmode install, why do you even want to use the UAC plugin in the uninstaller to begin with?

Originally posted by Anders
...And why the AsUser stuff cannot be used in the uninstaller? Well, with a uninstall registry entry in HKLM, Vista will auto-elevate so there is no way for me to get a outer instance. Sad but true.
This is not correct. You can do dualmode uninstallation without trouble, and AsUser works just fine in that case. It's true that Vista and 7 automatically force elevation when the uninstaller is called through HKLM ARP, but I remind you of this workaround:
http://forums.winamp.com/showthread.php?threadid=277801

MSG ...

Maybe you can give me some advice what "strategy" will be best for my project?

The program the installer + uninstaller is for is ment to be an all-users application. So it should always be installed for all users ($PROGRAMFILES).
And "by design" normally there should only be one version installed at a time. But for testing purposes it should also be allowed to install multiple (different) versions parallel.

In previous versions the config folder was placed in a per-user location. Starting with the new installer script the location changes to the all-users $APPDATA.

So regardless of how many versions of the program are installed there is always only one config folder (same settings for all versions - this is meant by design and not changeable).

And due to changes in the installer of previous versions there might be Registry entries in HKLM as well as in HKCU.

Shortcuts in the Start Menu and Desktop are all in the all users enviroment (AFAIK).

So here is a list of what the installer + uninstaller should be able to achieve:


The more I work with NSIS the more I get confused ...!
There are so many traps you can walk right into ...!


Originally posted by MSG
Netsurfer, if you're not doing a dualmode install, why do you even want to use the UAC plugin in the uninstaller to begin with?
I guess you are right. I now believe that it might be best to set the RequestExecutionLevel to admin and not using the UAC plugin.

Thanks for your help/ advice!

Gunther

Originally posted by Netsurfer24
And due to changes in the installer of previous versions there might be Registry entries in HKLM as well as in HKCU.
First advice: Don't get these mixed up. Since your installer only supports all-user mode, completely ignore any old HKCU entries. Just leave them be, they're not doing any harm as long as you don't use them. (As for old HKCU uninstall entries, well, that's less obvious - you could try using enumusersreg to eradicate all older uninstall entries, if necessary.)


Originally posted by Netsurfer24
So here is a list of what the installer + uninstaller should be able to achieve:
  • multi language capable
  • install for all-users
  • write RegKeys to HKLM
  • search for previous installations and remove them along with possible RegKeys, Shortcuts etc.
Most of this is quite simple. Multi-language support is built-in to NSIS. You already know how to install for all users, and how to use HKLM registry. Searching for previous installations is kind of weird, because you just stated that you wanted to allow old installations in parallel, for testing purposes. But you can use enumusersreg, again, to purge any junk from all users' registry hives. (Deleting userlevel shortcuts for other users is not possible, sadly. There is however a workaround described here, which works some of the time.)

MSG

thanks for your helpful answer.

Originally posted by MSG
First advice: Don't get these mixed up. Since your installer only supports all-user mode, completely ignore any old HKCU entries. Just leave them be, they're not doing any harm as long as you don't use them. (As for old HKCU uninstall entries, well, that's less obvious - you could try using enumusersreg to eradicate all older uninstall entries, if necessary.)
The problem is that I wanted to use these "old" entries to detect if any older version is already installed (for showing an Upgrade option to the user). I also added an option to scan the entire HDD but this may last several minutes so this nothing I want to be executed by default.
And in my opinion it is unpleasant if there remain orphaned Reg entries.


Most of this is quite simple. Multi-language support is built-in to NSIS.
Yes, that's no problem.
But how about language support? Are there any languages (supported by NSIS) that need to use the Unicode version or is it possible to use the ANSI version even if I want to support languages like Russian?

You already know how to install for all users, and how to use HKLM registry.
Yes, that should make no problems. :)

Searching for previous installations is kind of weird, because you just stated that you wanted to allow old installations in parallel, for testing purposes. But you can use enumusersreg, again, to purge any junk from all users' registry hives. (Deleting userlevel shortcuts for other users is not possible, sadly. There is however a workaround described here, which works some of the time.)
I already found the EnumUsersReg.nsh and played around with it yesterday. I managed to get the Appdata and Start Menu folders from all (logged-on/-off) users. But you say it is not possible to delete Shortcuts in these folders?

And once again a question concerning the UAC. I wrote a small test script for the EnumUsersReg and though I set "RequestExecutionLevel admin" I can start the exe as a standard user if I have UAC set to off (I am on Win 7).
So do I have to add a manually check within my script if the user is Admin and quit if not?
I checked the Manifest of the file and it says:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Nullsoft.NSIS.exehead" type="win32"/><description>Nullsoft Install System v2.46-Unicode</description><trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges><requestedExecutionLevel level="requireAdministrator" uiAccess="false"/></requestedPrivileges></security></trustInfo><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/><supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/></application></compatibility></assembly>
Many thanks,
Gunther

PS: Here's the script

RequestExecutionLevel admin 


>Var sid
>Var USERPROFILE

>!include WordFunc.nsh
>!include EnumUsersReg.nsh

Name EnumUsersReg
OutFile EnumUsersReg
.exe

ShowInstDetails show

Section
; use ${un.EnumUsersReg} in uninstaller sections
${EnumUsersReg} GP tmpkey
SectionEnd


>Function GP
Pop $sid

ReadRegStr$1 HKU "$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" AppData
${WordReplace} "$1" "%USERPROFILE%" "$USERPROFILE" "+1" $2
DetailPrint$2

ReadRegStr$1 HKU "$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" "Start Menu"
${WordReplace} "$1" "%USERPROFILE%" "$USERPROFILE" "+1" $2
DetailPrint$2
FunctionEnd
>
But I made some slight changes to EnumUsersReg.nsh, too:

Originally posted by Netsurfer24
Are there any languages (supported by NSIS) that need to use the Unicode version or is it possible to use the ANSI version even if I want to support languages like Russian?
No idea, I only use English installers. Search the forums?

Originally posted by Netsurfer24
But you say it is not possible to delete Shortcuts in these folders?
Deleting should work fine. Finding the directories is that part that doesn't work.

Originally posted by Netsurfer24
And once again a question concerning the UAC. I wrote a small test script for the EnumUsersReg and though I set "RequestExecutionLevel admin" I can start the exe as a standard user if I have UAC set to off (I am on Win 7).
So do I have to add a manually check within my script if the user is Admin and quit if not?
Yes, an extra manual check is always required.

Originally posted by MSG
Deleting should work fine. Finding the directories is that part that doesn't work.
Hmmm ..., I am using my modified version of EnumUsersReg.nsh (see posting above).

It searches for the values of the RegKeys
  1. HKU "$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" AppData
  2. HKU "$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" "Start Menu"
Whereas $sid is the user's SID (if logged-on) or the temp key its hive is loaded to (if logged-off).

The %USERPROFILE% variable is replaced by the value deriving from:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<SID>\ProfileImagePath

I thought this should work correctly for all Win >= Win 2000.

Have I overlooked anything?

Yes, an extra manual check is always required.
OK - understood.
Is it "normal" that if UAC is disabled/ off one cannot start an exe file by "Run as administrator"?
I added a query if user is admin to my small test script. So when started as a standard user it quits. But I cannot start it in any way - no prompt for admin credentials is ever shown.
So do I have to use the UAC plugin to allow running a program as administrator in the case UAC is disabled?
Really, this UAC thing totally confuses me ... - sorry.

Gunther

It's pretty simple up to the point where you start to do tricky things, really.

In one of your more recent posts, you noted that you always install as admin - so we can forget about most of those tricky things; it just leaves you with needing to make sure that your installer runs as admin.

"RequestExecutionLevel admin" is what takes care of that on any of the Windows versions that take that manifest into account (UAC or not, but UAC is the typical path).
If there's no mechanism taking that into account (UAC off and no alternative running), you only have to check whether the installer is running as admin and warn the user that the installer will not continue if it isn't.

That just leaves you with your remaining question... "How can i tell a user to run something as admin in the latter case?". Most typically, that would be done by right-clicking on the installer executable, and choosing the "Run as administrator" option (Vista / Windows 7) or "Run as" followed by the user selecting an administrator account (XP). Screenshots:
http://www.asap-utilities.com/faq-qu...tail.php?m=109

If you're not doing anything else, like needing to run an application as non-Admin, or installing files in non-Admin's profile, UAC isn't really anything you need to worry about.


Originally posted by Animaether
That just leaves you with your remaining question... "How can i tell a user to run something as admin in the latter case?". Most typically, that would be done by right-clicking on the installer executable, and choosing the "Run as administrator" option (Vista / Windows 7) or "Run as" followed by the user selecting an administrator account (XP). Screenshots:
http://www.asap-utilities.com/faq-qu...tail.php?m=109
Except that "Run as administrator" menu option does not work on Vista when UAC is turned off

Originally posted by Anders
Except that "Run as administrator" menu option does not work on Vista when UAC is turned off
Yes, same on Windows 7 and UAC turned off.

Therefor I still use the UAC plugin just to make sure the RunAs Dialog will be displayed.

Gunther

Originally posted by Netsurfer24
Therefor I still use the UAC plugin just to make sure the RunAs Dialog will be displayed.
Yeah, that is because the UAC plugin detects this and uses its own internal RunAs dialog in this case on NT6.

In this kind of setup, requestexecutionlevel admin+uac plugin is fine, just remember that the AsUser macros don't "work", all you can use the plugin for is the initial elevation

Anders,

I have to check back - sorry.

Originally posted by Anders
Yeah, that is because the UAC plugin detects this and uses its own internal RunAs dialog in this case on NT6.

In this kind of setup, requestexecutionlevel admin+uac plugin is fine, just remember that the AsUser macros don't "work", all you can use the plugin for is the initial elevation
I wanted to use requestexecutionlevel highest + UAC plugin.
And the installer checks if the user has admin privileges. If not it quits (with a message box).
And the AsUser macros work fine for me (at least for the installer). For the uninstaller they do not (but it is not needed, so no problem). My uninstaller also needs Admin privileges and again I use the UAC plugin to assure this.

But anyway, if someone wanted to know some user specific (path) information despite if the user is logged-on or not, one can use the EnumUsersReg.nsh to gather these information (admin rights presumed).

Gunther

Originally posted by Netsurfer24
But anyway, if someone wanted to know some user specific (path) information despite if the user is logged-on or not, one can use the EnumUsersReg.nsh to gather these information (admin rights presumed).
As I have been trying to tell you: This is not true. Yes, you can *usually* get the path from registry (using EnumUsersReg). However, the path is not guaranteed to be stored in registry at all. For example, on a freshly installed Windows operating system, you can be almost sure that the value will NOT be stored in the registry. Even worse: Even if it is stored in the registry, it is not guaranteed to be correct!

Granted, in most cases, this isn't too big a problem. But you need to keep it in mind. That's why using EnumUsersReg to get a user's profile folder location is an ugly workaround at best. Use it only if you know what you're doing.

Originally posted by MSG
As I have been trying to tell you: This is not true. Yes, you can *usually* get the path from registry (using EnumUsersReg). However, the path is not guaranteed to be stored in registry at all. For example, on a freshly installed Windows operating system, you can be almost sure that the value will NOT be stored in the registry. Even worse: Even if it is stored in the registry, it is not guaranteed to be correct!
As I need the (path) values only in case the respective user has installed the program before, I guess the values are present. ;)

Granted, in most cases, this isn't too big a problem. But you need to keep it in mind. That's why using EnumUsersReg to get a user's profile folder location is an ugly workaround at best. Use it only if you know what you're doing.
I understand what you are saying, but again ...

I only use these values to delete/uninstall previous installed versions and/ or existing shortcuts. Additionally I "clean-up" each users registry (if there are orphaned entries).

ALL new installs, shortcuts etc. will be done in the all-users context.

But thanks for reminding me. :up:
And yes, I do not trust any single value without proofing/ testing it. :D

Thanks
Gunther