Search code examples
c#setup-projectvisual-studio-setup-projefile-security

Can't Add Full Control to Settings File


I have a C# application which stores it's settings in ProgramData subfolder such as

C:\ProgramData\Manufacturer\Product\Version\Settings.xml

I noticed that the application can't save settings changes, getting a permission denied error. My work-around was to manually change security settings and give Everyone full control on the folder tree and file. This works, but I'd like a more robust method.

Using suggestions from SO, I created the following code:

private void set_permissions()
{
    try
    {
        // Create security idenifier for all users (WorldSid)
        SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);

        // get file info and add write, modify permissions
        FileInfo fi = new FileInfo(settingsFile);
        FileSecurity fs = fi.GetAccessControl();
        FileSystemAccessRule fsar = 
            new FileSystemAccessRule(sid, FileSystemRights.FullControl, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow);

        fs.AddAccessRule(fsar);
        fi.SetAccessControl(fs);
        LogIt.LogInfo("Set permissions on Settings file");
    }
    catch(Exception ex)
    {
        LogIt.LogError(ex.Message);
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

When I step through the code, I get

Attempted to perform an unauthorized operation exception

when I execute this statement:

fi.SetAccessControl(fs);

If I close Visual Studio 2015 and open it as administrator, then my code will execute properly and the file security now has an entry for Everyone with full control.

So finally, here comes the question:

I'm following suggestion of putting the above code in my application, then in the setup project I add a custom action to run the newly installed application with an Install command-line option. My application, if it sees "Install" argument, will run the above code. Since I'm using a setup project which installs for all users by default, it automatically gives the administrator prompt before install. Does that mean the entire session, including the special action to run the application after install, is running under administrator rights?

If so, this should work, right?

But if the person installing changes it to "This user" then it would not be running with admin rights, and my code will fail. If needed, I could always be the one to do the final install and therefore would always use the administrator prompt, but I hate to depend on that.

Is there a more proper way to do this?

Thanks...


Solution

  • It seems that your program is not running elevated and therefore cannot update files in that location, and I assume that you want your users to not require admin privilege that you could add using an elevation manifest in your program.

    So why choose that location to store the data? Why not just use User's Application Data folder?

    As for that code, it's probably more robust to add it as an installer class custom action rather than run an executable. In an Everyone install that runs elevated the code will run privileged with the local system account.