Search code examples
c++windowswinapiwindows-vistauac

UAC, requireAdministrator and files access


I have a problem with UAC on Vista/7.

My installer with UAC Execution Level requireAdministrator installs and runs my app.

  • App UAC Execution Level: asInvoker

So first time app runned by installer, it runs as administrator. Then, app creates some files to store self state.

Later (if app launched by user, not as administrator) app can only read from created files, but can't overwrite them.

I tried to disable UAC in the app manifest, or build app without manifest but result still same -- every file created when app runned as administrator can't be overwritten when app runs as user. I tried some other installers like Inno Setup but there nothing like my problem... So my question -- why it happens in my case and how to fix it ? Thanks.

P.S. Important notes

  1. Actually it is not installer. This is utility to update main app executables. Main app check server for updates, if any available -- downloads updates to the temp folder and then launch utility with elevated rights (http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx) in order to replace executables in the Program Files folder. Main app terminates just after launching utility.
  2. All files application stores in the ProgramData\myAppName folder.

Solution

  • Are your installing application for current user only or for all users on the machine?

    For per-user installation it makes sense for the installer to create initial application state in the user's AppData folder. MSI runs per-user installations NON-elevated, so there is no problem with files in AppData folder your applications cannot modify.

    For per-machine installation it does not make sense to put anything to the specific user's AppData folder or anywhere under users profile location. New users can logon on the machine after application is installed and they would not have anything there.

    That said, you have three solutions (actually two solutions and one hack):

    1. Use per-user installation. Set ALLUSERS=2 and MSIINSTALLPERUSER=1. Your MSI will be run non-elevated. MSI is free to put any state files in AppData folder.
    2. Use per-machine installation. Don't write to users's appdata. Instead, write initial state files into %ALLUSERSPROFILE%. They will be Read-only to application. Modify your application to copy initial state from %ALLUSERPROFILE% to current user profile on first run.
    3. Add custom action to your installer to add user to ACLs.

    (#3) is a hack and I don't recommend it, because your application would be broken for new users, or when user re-creates his profile on machine.