Install files to original user's My Docs folder via Inno Setup on Windows Vista/7 - windows-7

In the [Run] section of an Inno Setup script, there's a flag runasoriginaluser that allows the script to run a process as the original user:
the spawned process will execute with
the (normally non-elevated)
credentials of the user that started
Setup initially (i.e., the "pre-UAC
dialog" credentials).
Is there an equivalent flag or workaround for the {userdocs} shell folder constant?
This is apparently a known limitation within Inno Setup (and other installers, generally), but I'm hoping someone knows a workaround.
Excerpt from the Inno Setup help file:
The "user" constants refer to the
profile of the user running Setup.
This user is often not the same as the
currently logged-in user, so use the
"user" constants with caution.

The workaround I came up with was using an external script to perform the data copy and calling the script using the ExecAsOriginalUser function in the wpReady page of the NextButtonClick event function.
I'll provide more details if anyone is interested.

Your approach is not correct.
There two correct ways:
If the installer installs the application for the current (unprivileged) user only, do not require Administrator privileges, by setting PrivilegesRequired to lowest:
[Setup]
PrivilegesRequired=lowest
Then the "user" constants will correctly refer to the current user's folder.
If the installer installs the application for all users, it does not make sense to put some files to folder of one specific users. All users need the files, not just the one. In this case the recommended approach is to install the files to "Common" folder, using the {commonappdata} constant (or similar). And have the application copy the files to the user folder on the first run.
See also How to write to the user's My Documents directory with installer when the user used 'Run As Administrator'.
You can also allow the user choose between these two approaches.
See Make Inno Setup installer request privileges elevation only when needed.
For another similar questions, see
Inno Setup Using {localappdata} for logged in user
Inno Setup always installs into admin's AppData directory
Having that said, you can, as you have found yourself, by execute an external copy utility (copy, xcopy, robocopy) using the ExecAsOriginalUser function (or the runasoriginaluser flag in the [Run] section).
ExecAsOriginalUser(
'cmd.exe', '/c xcopy.exe "sourcefile" "%APPDATA%"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
For more detail on this approach, see a similar question Inno Setup Creating registry key for logged in user (not admin user).
Though, if the installer was started elevated straight away (as opposite to elevating itself), the above won't work. And it cannot work in this scenario anyway. See How to write to the user's My Documents directory with installer when the user used 'Run As Administrator'. For this reason, stick with the approaches described above.

Related

Inno Setup : how to integrate admin credentials in the installer

I want to create an installer that:
- install a software package
- copy a host file in the user system
without any user installation except launching the installer.
I need this installer to run as admin but I do not want to disclose the admin login/password to users but instead I want to embed it in the installer itself. How can I insert the admin credentials within the installers, please ? Is it even possible ?
I've looked into the forums but did not find what I'm trying to do.
Thank you for your help and support,
Fred
You basically need this:
Make Inno Setup installer request privileges elevation only when needed
(the old code in the second part of my answer with an explicit code for the elevation for Inno Setup 5)
Except that instead of simply re-running the installer with runas verb (which needs entering the Administrator credentials manually), you need this:
Inno Setup run/execute code as another user

After aborting the installer if i try to install again, installer is still pointing to old path

I am trying to install a installer developed using InstallShield 2008. While installing after selecting the destination path i am aborting the installation.
When i try to install again by default it is taking the destination path as previously given path which was provided before aborting the installation.
And also it is not allowing me to install in different path.
For Example:
*Step1 : Installation starts
Step2: Destination path as C:\Installer
Step3: Click next and abort installation
Step4: Start the installation again
Step5: Provide Different destination path as C:\Installer1*
Here installation is failed. Because destination is still pointing to Step2
My question is from where Installer is taking the old path.?
Persisted Path: The technicalities appear to be relatively straightforward: the old path is read back either from the registry or from disk each time the setup is launched, and a custom action in the setup's GUI sequence must have persisted the path "somewhere" during the first run (this is erroneous design, see technical comment below). Reading back the value can be done by using AppSearch (built-in MSI feature) or by means of a custom action.
Registry / Disk: As to finding where the value is read from. The easiest would be to just search the registry first for the literal path. Just open regedit.exe and search for the path there. You can also look for the custom action that does the persisting (or the AppSearch or custom action that does the retrieval) and see if it is a script with code you can see - then you should be able to see where it has persisted the path. Use Orca or a similar tool to view the Custom Action table. The custom action can also be compiled and undecipherable. Do you have the setup source? The path can also be persisted to disk, but the registry is most commonly used. Remember to search both HKCU and HKLM.
Involved Debugging: I can't see why you would, but it is also possible to use ProcMon.exe to monitor what registry locations your MSI reads and / or writes to. This is involved debugging and should never be needed for something this simple. Just mentioning it as a technical option. Generally the last resort we have to figure out the strangest problems.
Technical Comment: MSI setups are not supposed to write anything to the registry or disk from the setup's user interface sequence (setup dialogs). All changes should be made from the installation sequence (InstallExecuteSequence) which also generally runs with elevated rights - the user interface normally runs with user rights. This InstallExecuteSequence sequence is kicked off from the last dialog in the GUI sequence, and runs the file copy and system change operations. Control then returns to the GUI sequence to show the setup complete dialogs. It is also possible to run the setup silently, in which case the InstallUISequence never runs and all custom actions inserted there fail to run. Accordingly custom actions should be present in the InstallExecuteSequence as well as the InstallUISequence if they are to run in silent mode. This potential design flaw is a very common silent deployment error which occurs when setups are not designed properly for silent running. Remember that all corporate deployment runs silently. Setup GUI is highly overrated (in my opinion - a "fact" that could change in the future).
It is still possible for an MSI setup to write to the registry or disk from the InstallUISequence by using a custom action to do so. Such a custom action would normally not have access to write to HKLM or to protected parts of the disk - unless the whole setup runs elevated because it was launched from an elevated command prompt (for example), or launched by an admin who elevates it via the UAC prompt.
In other words: this setup is badly designed, but I guess that is clear already.

Change registry value permission command line or NSIS

I'm trying to grant ordinary users write access to a registry value I created.
They cannot have write access to the parent key.
Through regedit, it's simple:
1. Select value
2. Edit Permissions (change accordingly)
3. OK
However I'm struggling to do the same via command line or NSIS.
The command regini has a very nice method for changing key permissions. If this worked for changing value permissions, I could easily script it into my installer.
The NSIS plugin AccessControl has a very nice method for changing key permissions but no evidence of changing value permissions.
In this case, the key is HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run which I will not modify the permissions of.
How can I change only the permissions of the value I've created? How can I do this just as regedit allows, but silently through command line or NSIS?
The value would be something like:
[HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
"My Value"="C:\Please\Let\Me\Change\Permissions\Sadface.exe"
Note, this is for scripted software installer which build script will run on Mac, Linux and Windows (NSIS allows this). Recommendations for bundling special dlls or Windows executable is OK so as long as they're easily bundled and chained against at install time. Solutions including tools such as Windows SDKs cannot be accepted unless the footprint is small and so as long as the DLLs can easily be bundled and included into a LGPL 2.1 project. e.g. installing users will have to run this, so solutions need to be reasonably portable/distributable.
As #Noodles mentions in the comment above, it's not possible to change value permissions, so no solution exists. Registry editor is actually providing the key permissions, which is observable by looking at the Window title, and which is undesired for this particular solution.

How to delete application file from AppData\Roaming folder

I am using windows installer to create setup project.
How I can remove/delete application files from AppData\Roaming folder when application uninstalled.
I tried added a special folder and set DefaultLocaltion to [AppDataFolder] but it didn't working.
Do I need to do anything else?
I'd need to understand what you are trying to do to give you specific advice. In general what you are trying to do would be OK removing files from CommonAppDataFolder but not AppDataFolder as trying to clanup user data from multiple user profiles is not a best practice. Additionally trying to cleanup Roaming Profile User data is outright impossible because the other users aren't logged on.
You'll want to read:
Managing Roaming User Data Deployment Guide
Assuming you are trying to do what I think you are, you'll need a cleanup script / exe that you leave behind on uninstall and a custom action to write to the registry during uninstall ( MSI can't do this natively ) to call that script/EXE. You'll want to leverage the Active Setup trick as described here:
Using Active Setup to Repair User Settings
The way it'll work is your uninstall leaves the EXE and registry entry behind so that when a user logs on it's roaming data gets pulled down from the server to local and Active Setup realizes it hasn't run the script yet. The script runs (once) and the data is deleted. When the user logs off the data is replicated / deleted on the server. Then they log on again it doesn't run again.
By default Windows Installer does not remove the files created by your application, after the installation. To do that you need to either write your own custom action, that will run upon uninstall, or depending on the tool used for authoring the MSI, you can use built-in options for cleaning the application locations, as some tools have this support.

Inno Setup: How to get current user directory when running installer as admin?

I need to write a ini file to the current user's directory in Windows 7 (C:\Users\CurUser). CurUser is not an admin. My installer requires admin privileges. So my setup looks like this:
[Setup]
PrivilegesRequired=admin
When I run the installer it prompts for the admin to login. From that point on, all the user constants, userappdata, etc, are C:\Users\AdminUser... So I need a way to find the CurUser when running the install as AdminUser.
Code examples are appreciated. Thanks.
All user specific files/settings that the app requires should be written by the app if they are found not to exist.
If it needs to come from the setup, you can write it into a global location as a "default" for the app to copy or use.
This also means your app will work for ALL users on the system rather than just the user that ran the setup.
You should split your setup into two parts. The first non-admin part writes the ini file to the current user directory and it calls the second setup part which requires admin priviliges.
In my case, I just switched to {commonappdata} instead of {appdata}, as my data was the same for all users.

Resources