I have a Win32 application that includes an EXE, an ActiveX control (DLL) and a COM server (EXE) and I am using Inno Setup 5 to build my installer. Many of our customers use limited user accounts where the user has no admin rights and because the COM components require to be registered (which writes to HKEY_CLASSES_ROOT), my setup file must run with elevated (admin) privileges. I think this in unavoidable (sadly, I can't use registration-free COM because of the EXE COM server I have). However, I would like to create an update installer that can be ran as a limited user and am looking for some advice.
What I am thinking is the following:
The initial setup (first time installation) installs the application into %ALLUSERSPROFILE%\Application Data\CompanyName\AppName instead of %PROGRAMFILES%. The COM components are registered as normal (as they won't already exist).
Subsequent updates (using a different Inno Setup script) will simply copy the new files into %ALLUSERSPROFILE%\Application Data\CompanyName\AppName. Hopefully even a limited user will have write access to this folder and as the COM components have already been registered, admin access won't be required.
This would mean that my customers could upgrade to the latest and greatest version without the hassle of using an Administrator account. Is this acceptable or is this likely to bite me on the backside? I'm pretty sure Google Chrome does something similar but as it has no COM components (as far as I can tell) even the initial setup can be as a limited user.
Any advice from others who have faced this issue would be very welcome indeed.
OK, I found a way to create a limited-user installation script with both my COM server and COM objects being registered per-user.
I am using the latest version of ATL (v9) that ships with MSVC 2008 to create my COM server and COM objects. Turns out that you can register the COM server per-user via the new /RegServerPerUser switch. I tested this with limited user accounts on XP, Vista and Windows 7 and it works perfectly.
Next, the COM controls. Again, ATL9 to the rescue. You can register a control per-user by ensuring that RegSvr32 calls your control's DllInstall function, passing it a command-line parameter of user. So, to register a control in this way you simply do:
regsvr32.exe /i:user /n MyControl.DLL
Again, I tested this on XP, Vista and Windows 7 and it works fine.
I then made the following changes to my Inno Setup script:
The default installation folder will be {pf} (i.e. C:\Program Files) if the user has Admin rights. If not, then it defaults to {commonappdata} (i.e. C:\Documents and Settings\All Users).
Register my COM server using the new /RegServerPerUser switch.
I removed the regserver flags from my COM objects and instead added support to call regsvr32 using the new 'user' switch.
All of these changes are easy to do using the Inno Setup {code} feature.
Thanks to Kim for setting me down the per-user COM install path.
I don't know for sure, but I seem to recall COM servers support per-user installation, and maybe that goes for EXE servers as well.
If so, change your registration code to write information to HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT.
The COM infrastructure should do the lookup first per-user and then per-machine.
It's worth an experiment anyway.
If you dumped inno-setup and used MSIs - MSI files support the idea of limited user installation of patches. An administrator must authorize the initial install, thereafter, digital signatures in patch msi files are processed by the elevated msi service without requiring user elevation.
You can duplicate this basic idea yourself - during an initial administrative install, install a service component that has the necessary access. When processing patches, ask the service process to process the EXE COM server registrations.
You need to rethink your approache ... write access to a folder than can also allow for program execution by the same user is the cause for 99% of all virus/malware functionality. Please learn a little about Software Restriction Policy and the new App Locker behavior built into Windows 7 so that the computing infrastructure can move forward not backward.
Related
I maintain a large Windows C++ Application that installs with nullsoft nsis. Installation is quick and simple (less than 1 minute).
Some users in large companies do not have administration privileges and they have to order costly 3rd party services to update their installation. Therefore some of them only update once a year, while we ship every month and sometimes fix important bugs etc.
So we are thinking about automatic updates that do not require elevated administration rights. Mozilla and Adobe do this as well as others. As far as i can see an the Mozilla XULRunner site they install a service which then in turn can run a update without forcing the user to enter a administration password. I also found Googles Omaha but it is not clear about the administrator privileges ("Support for restricted user environments; for example, users without administrator privileges "..."This requires the user has administrator privileges.").
So far i have not found exact answers to these questions:
What steps do we have to take in order to establish such a mechanism?
Can we keep on with nsis?
What server infrastructure is requested?
Your application should check for updates on your server/website and get the download link.
This should be pretty easy if you maintain a text file/page with fixed hyperlink.
This hyperlink can be hard-coded in your application.
If it detects a version newer than the current version then download the files.
Along with these files there should be instructions for which files to replace and Which files are to be added at what location, etc.
Now whether or not you need admin privileges depends on where you need to place the updated files. If the target folder has some restrictions then it would be difficult to update in the same session. So you may have to launch a dummy exe which asks the user for admin privileges during startup. Now you can copy the updated files to your desired location without much pain.
I'm porting my application on Windows 8. Program uses path
C:\ProgramData\MyProgramName\
for storing backups.
It works good on Windows 7, but it got "Access Denied" when I run it on Windows 8.
What is the proper way and place to store my program's backups (not related to any particular user) ?
I see many programs storing their non-user related application data in the common application folder. Ok, actually what they do is create a folder inside the common application folder to store their data.
To get the path to the common application folder, you can call the SHGetFolderPath function with CSIDL_COMMON_APPDATA as the folder id. If don't have to support anything earlier than Windows Vista then you can call the SHGetKnownFolderPath function instead, and pass FOLDERID_ProgramData as the known folder id.
Ah! I did not know that the common application folder is not-writeable by normal users. Luckily there appears to be a recommended solution. See this article on MSDN, Data and Settings Management which states the following "If an application requires normal Users to have write access to an application specific subdirectory of CSIDL_COMMON_APPDATA, then the application must explicitly modify the security on that sub-directory during application setup. The modified security must be documented in the Vendor Questionnaire."
C:\ProgramData has security settings that prevent standard user from writing there. This is not new in Windows 8, Windows 7 was the same, and the equivalent folder on Vista is also secured in this way. Perhaps your Windows 7 environment has UAC disabled, or perhaps you have secured C:\ProgramData or C:\ProgramData\MyProgramName to permit write access to standard user.
There are a couple of approaches to the use of this folder. Some applications write there only during installation whilst the installer process is running elevated. Then the application itself, which runs as standard user, can read, but never attempts to write.
Another approach is for the installer to create a sub folder of C:\ProgramData that is secured to allow write access for standard user, or whatever user/group that you the developer deem appropriate.
I am trying to release a C++ .Net application and am getting very frustrated with Windows UAC. I have not much experience with this as have always been writing for XP.
The program needs to update some properties that are stored in two XML files and every time it tries it gets access denied if it is not running with an Administrator account.
I have followed the recommendations from Microsoft and am writing all the files that need to be modified to the CSIDL_COMMON_APPDATA folder. The installer has an action that creates the [Organization}[Program] structure within the later and adds the security group Every One with full control privilege because by default, that directory is read only.
I have verified that the cretated directory [Organization}[Program] does actually contains the group and the privilege assigned after installing.
Also, the application has a manifest with a requestedExecutionLevel, which I have tried asinvoker and Highestavailable.
The application is still not being capable of writing to the directory unless the user is not logged as Administrator...
The machines are in a domain controled by a server 2003 but the clients are a mix of XP, vista and 7.
Please, could someone with more experience in this than I enlight me?
Should I use some other folder? The problem is that Different users might log into the computer and those settings are common, therefore the obvious User folder is not an option.
I cannot either add the user to the security of the folders with the installer because I don't know which user from the domain will use the program and I cannot do it from the program when starting because if the user does not have adminstrator rights the program will just be blocked.
Please, any advise or indication about what am I missing here?
This may discuss your problem. See especially
Your application's installer needs to set ACLs on your subdirectory of CSIDL_COMMON_APPDATA to allow users to access that directory as required by your application
I have created a windows install deployment for my C++ application using VS2010. However my problem is that I don't know how can I squeeze in some of my own code to the installation wizard (and is it possible at all?). The problem is that during installation I want:
ask the user to provide his installation key,
grab the hardware fingerprint (I already have an algorithm for that with WMI),
sent both keys using my own c++ communication libraries (so NOT the browser),
continue the installation after receiving a confirmation from the server.
Moreover, this would require adding custom items to the installation wizard like the input field for installation key, or pop up boxes witch error warring like:
Couldn't connect to the server. Please check your internet connection before continuing with the installation.
So it's in fact a 2 level question:
How to run my C++ source files during the installation wizard?
How to add custom element to the installation wizard GUI?
So far it has been hard to find anything helpful in Google. :/
Check Windows Installer, more specifically Custom Actions:
The developer of an installer package may write code to serve their own purpose, delivered in a DLL. This can be executed during the installation sequences, including when the user clicks a button in the user interface, or during the InstallExecuteSequence. Custom Actions typically validate product license keys, or initialise more complex services. Developers should normally provide inverse custom actions for use during uninstallation.
Msiexec provides a way to break after loading a specified custom action DLL but before invoking the action.
im writing an application that downloads and installs addons for programs which needs to save the data to program files (for the programs in question). Now this works fine on xp and vista with uac disabled however it is failing on normal vista due to the virtual folders.
How would one get around this with out needing to request admin rights every time the app started?
P.s. Program is written in c++, vis 2005
Edit: File system virtual folders: http://www.codeproject.com/KB/vista-security/MakingAppsUACAware.aspx
Only write to Program Files during installation. After that, write to the user folders.
You can elevate the apps privileges later, but you'll just be delaying the prompt. The whole point of UAC is to prevent random apps from writing to folders that require admin privileges. (ok, not the whole point, but a large portion of it.)
You could create a service with admin privileges and send commands to it to move the downloaded files into the desired target directories, but this opens up a user's system to being abused by other apps if you don't design it very carefully.
This article talks about getting apps to work nicely with UAC. Also, see this article here.
Microsoft recommended to me when I spoke to them to have to write a second application, which you manifest as requiring administrative privileges. You use this application to deploy your file from a safe location (such as the users programdata directory) to the program files directory (Note that if your DLL isn't signed then this is a massive security hole as a virus/malicious user could manipulate the file before your function call).
Your non administrative app can call this application which will trigger UAC. People who understand UAC won't care and happily will click your application. Those who hate it will have switched it off. The call to start the new process (which required admin privileges) will throw a win32 exception if the user cancels the UAC dialog so beware to catch that.
The problem in vista is that it tries to help you by virtualising your program files directory if you are not admin. By design there is NO way that you can write to the program files directory unless you're administrator.
Another option is to create all of your "updates" as MSI updates. That way the windows installer will trigger UAC for you and you could provide a logo for your software etc.
Option 3 is to use clickonce deployment which will allow you to automatically update your program without UAC but you live in a sandbox on the users system which may not work with your application's current design.
I got around uac by making a windows service that does the work i need and only runs while the app is running.