NSIS: get current user before RequestExecutionLevel admin - installation

My installer run in all users, and it saves user information in the AppData folder.
The problem is that, when the installation is finished, an executable is launched by means of an Exec and it is launched as the administrator user, so all the session data is stored in the administrator's AppData. I want to run the installation as Admin but the last step as the current user.
RequestExecutionLevel admin
Can I launch my application as the current user? Can I keep the current user before ask for admin privilages?

The Microsoft guidelines say:
Certification requirements for Windows Desktop Apps
Apps must install to the correct folders by default
10.6 Your app must write user data at first run and not during the installation in per-machine installations. When the app is installed, there is no correct user location in which to store data.
If you have some sort of default user data/template you should install that in %ProgramFiles% or %ProgramData% and your application should copy that data to %AppData% the first time a user runs your application.
The ShellExecAsUser and StdUtils plug-ins can be used to execute your application as the "real" user on the finish page.
The UAC plug-in allows you to access the "real" users %AppData% and registry but I don't recommend this approach because the plug-in is hard to use and it really promotes incorrect behavior. You are very likely to end up with a install pattern that only works for the initial user and not other users on the same machine.

Related

Installing application for currently logged in user from Inno Setup installer running as Administrator

A very common question about creating (Inno Setup) installers revolves around accessing/modifying a profile of a specific user (the currently logged in user) from an installer that runs with elevated/Administrator privileges.
Doing this has many drawbacks and is error prone.
All the existing answers cover part of the problem (registry, files, desktop icon, etc). A purpose of this question is to collect answers that address the problem globally, with all possible approaches.
Inno Setup does not have any built-in mechanism to access or modify user environment from installer running with elevated/Administrator privileges.
All the attempts to achieve this rely on tricks like:
runasoriginaluser flag or ExecAsOriginalUser function. Some examples:
Modifying or accessing registry of logged in user:
Inno Setup Creating registry key for logged in user (not admin user) or
How to read registry HKCU for logged In user from Inno Setup installer running as administrator
Accessing AppData folder of logged in user:
Inno Setup always installs into admin's AppData directory or
Inno Setup Using {localappdata} for logged in user or
Inno Setup - puts user files in admin documents.
or using {user*} constants.
Though these are not reliable, at least for these reasons:
When the current user does not have Administrator privileges, (s)he needs to enter Administrator credentials on installer UAC prompt. That switches the installer to a different user. So {user*} constants will not refer to the user that initiated the installation.
When the user explicitly runs the installer with elevated privileges, e.g. by right-clicking the installer and selecting "Run as administrator" or running it from another elevated application (file manager), the "original user" for runasoriginaluser flag or ExecAsOriginalUser function will already be elevated.
In corporate environments, applications are installed by Administrator, who is not the user that will be using the application.
The only correct generic solution to this problem is to defer a setup of the user environment only to the actual user session.
Easiest is to have the application itself do the setup on its first run.
The installer can only deploy shared files that the application can use for the setup.
If you cannot modify the application for whatever reason, you would have to iterate all accounts and modify them:
for files: Inno Setup Create individual shortcuts on all desktops of all users
for registry: Uninstall auto-run registry entries for all users
If you need to make sure the settings get distributed to accounts that get created only after installation, see How to install files for each user, including future new users, in Inno Setup?
If you are happy with a fact that the application will be setup for the logged in user only, use PrivilegesRequired=lowest:
[Setup]
PrivilegesRequired=lowest
Then the {user*} constants will correctly refer to the current user's folder.
If you still need Administrator privileges for some sub-task of the installation, you can requests privileges elevation for the sub-task only:
Inno Setup - Register components as an administrator
Inno Setup - Access unprivileged account folders from installer that requires privileges
If you want to prevent user from breaking this by explicitly running the installer with Administrator privileges, see
Can't get Inno Setup postinstall Run item to runasoriginaluser or
my answer to How to write to the user's My Documents directory with installer when the user used 'Run As Administrator'.
Or you can programmatically find out, what is the account of the current Windows logon session:
Determine if Administrator account that runs elevated Inno Setup installer is the same as the account of the current Windows logon session.
Another option is to allow the installer to install for the current user only:
Make Inno Setup installer request privileges elevation only when needed

Why is my Delphi 6 program triggering a request for admin rights upon install on only a minority of Windows 7 systems (InnoSetup)?

I have a Delphi 6 program that for most users installs fine while running under a user account without admin privileges. However, on some systems it triggers a request for admin rights. Unfortunately mine isn't one of them so it's hard for me to diagnose this problem. I use InnoSetup 5.1.9 to build my install programs.
How can I figure out what I need to change about my installation program's configuration to neutralize the need for admin rights on some people's systems? It's causing trouble for my system because during installation, certain program data files are being copied into the admin account's application data folder. Then when my program is launched under a user account, those files can not be found since they are not in the user account application folder, where they are expected to be.
This happens due to default PrivilegesRequired directive value, which is, by default configured to require administrator elevation. If you don't need this, simply change in your InnoSetup script, value of this directive explicitly to something like this:
[Script]
PrivilegesRequired=lowest
From the reference:
When PrivilegesRequired is set to lowest, Setup will not request to be
run administrative privileges even if it was started by a member of
the Administrators group. Additionally, the uninstall info root key
will always be HKEY_CURRENT_USER, and the "common" forms of the Shell
Folder constants are mapped to the "user" forms, even if
administrative privileges are available.

How can I have my installer write to the HKCU registry tree?

My installer requires admin privileges. During installation some values are written to the HKCU tree of the registry of the currently logged on user. However, when this user account is a so called standard account, the user has to specify credentials for an administrator account when the installer starts. The values are then written to the HKCU tree pertaining to this admin account instead of the HKCU of the currently logged on user.
The same problem arises when the installer wants to write some data to the local AppData and wants to create a shortcut on the desktop.
How do I circumvent this?
This happens because you are using a per-machine installation which writes data in a per-user location (HKEY_CURRENT_USER).
The correct approach is to use either a per-user installation with only per-user locations or a per-machine installation with only per-machine locations (HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER).
If you are asking for admin rights it normally means you are doing a system-wide/machine install for all users. When creating this type of installer it is not a good idea to write to HKCU or %USERPROFILE%, not just because you can end up performing actions for "the wrong user" but you also end up initializing the install for just that one user and not all users.
What I recommend is that you write this common data to HKLM\Software\YourCompany\YourApp\CommonData and/or <CSIDL_COMMON_APPDATA|CSIDL_PROGRAM_FILES>\YourCompany\YourApp\CommonData and then import this data in your application the first time a user run's it.
You might also want to consider creating a per-user installer (like Chrome) but this means you can only write to HKCU and %USERPROFILE%!

Do applications installed to Program Files have permissions to modify their folder?

If I install my app to program files, will it always be able to create and write files within its install directory? It seems to work in a lot of different versions of windows, but are there situations where this wouldn't work?
Mainly I'm using this approach for logging. If this is not the correct approach, is there a better place to log?
Note: My installer requires Admin privileges to run and it grants Full Access to all users in the install directory.
Apps don't run as users, users run as users. If you install an app into Program Files, and let's assume you needed elevated permissions to do so, when your standard user then runs that app, that is the user that needs permissions.
App is installed with elevated permissions (user: Admin, for example)
All permissions on the AppName folder might well be "Admin:Full, Users:Read"
User runs app, so cannot change any files
At install-time, your installer will need to know which of it's own files need to be made writable to standard users, and set permissions accordingly. Of course, user-data should not be in Program Files anyway. That's what %appdata% and the user profile are for, usually.
If your app has a globalsettings.ini or whatever, that lives in "Program Files\YourApp", then while you have admin permissions (i.e. at install time) you need to grant write permission to all users to that globalsettings.ini file. Or Power Users. Or a group. Or whatever is correct for your app.
In summary, no, users do not have default write-access to ProgFiles, nor should they.
Yes, there are definitely situations where this won't work, such as when your app is running on Windows 7, or if your user account is a limited user.
We always put our log files in a temp directory or a special folder such as AppData.

Starting exe as a current user domain in Vista

I am starting an application (EXE) through Installer( MSI). While installing the MSI in Vista, it automatically run with Administrator rights (after thorough UAC). Hence the application started also runs under system user. I want this application to run Under Current User instead.
In order to run application in current user I need to explicitly double click the exe. But I want it to be done programmatically.
So far, the only way out is to use Process.start() using username/password. For this I need to prompt user and take password from him, which I dont want.
Can we run an exe under current user programmatically (Vista)?
Regards
Sumeet
If the installer, which spawns the program, is running under a user, for that program, "Current user" is that user, ie. Administrator in your case.
You will have to explicitly escape out to a different user context, and unfortunately this involves getting the user to specify his password (at the very least). Otherwise you could have programs impersonating users all willy-nilly.

Resources