Click here to Skip to main content
Click here to Skip to main content
Go to top

Allow write/modify access to CommonApplicationData

, 22 May 2010
Rate this:
Please Sign up or sign in to vote.
Now your application can update it's saved data regrdless of the account it is running under.
This tip was prompted by a discussion here[^] yesterday in the C# forum.
 
When you need to store data common to all users of an application locally, Microsoft recommend using System.Environment.SpecialFolder.CommonApplicationData. In addition they also suggest creating a sub folder here with your CompanyName and a sub folder in that of ApplicationName.
 
The issue with this is the folders and files you create only have read/execute permissions for other users other than the creator. This means that they cannot be appended to or replaced by another user without UAC elevation.
 
Whilst I understand the reasoning for this, in reality it creates a problem for a shared dynamic data store.
 
The class below addresses this by setting read/write permissions to all users on the CompanyName folder and optionally setting read/write permissions of the ApplicationName folder on creation and sub folders/files inherit these permissions.
 
Note: The permissions are only set on the ApplicationName folder creation. If it already exists the permissions will not be altered.
 
This has only been tested on Windows 7 to date, but should work fine in Vista and XP (if required?). I will test these OSes when time allows and update this accordingly.
 
Make sure you wrap any calls to this class in suitable try/catch blocks as there is no exception handling.
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
 
/// <summary>
/// Simplifies the creation of folders in the CommonApplicationData folder
/// and setting of permissions for all users.
/// </summary>
public class CommonApplicationData
{
    private string applicationFolder;
    private string companyFolder;
    private static readonly string directory = 
        Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
 
    /// <summary>
    /// Creates a new instance of this class creating the specified company and application folders
    /// if they don't already exist and optionally allows write/modify to all users.
    /// </summary>
    /// <param name="companyFolder">The name of the company's folder (normally the company name).</param>
    /// <param name="applicationFolder">The name of the application's folder (normally the application name).</param>
    /// <remarks>If the application folder already exists then permissions if requested are NOT altered.</remarks>
    public CommonApplicationData(string companyFolder, string applicationFolder)
        : this(companyFolder, applicationFolder, false)
    { }
    /// <summary>
    /// Creates a new instance of this class creating the specified company and application folders
    /// if they don't already exist and optionally allows write/modify to all users.
    /// </summary>
    /// <param name="companyFolder">The name of the company's folder (normally the company name).</param>
    /// <param name="applicationFolder">The name of the application's folder (normally the application name).</param>
    /// <param name="allUsers">true to allow write/modify to all users; otherwise, false.</param>
    /// <remarks>If the application folder already exists then permissions if requested are NOT altered.</remarks>
    public CommonApplicationData(string companyFolder, string applicationFolder, bool allUsers)
    { 
        this.applicationFolder = applicationFolder;
        this.companyFolder = companyFolder;
        CreateFolders(allUsers);
    }
 
    /// <summary>
    /// Gets the path of the application's data folder.
    /// </summary>
    public string ApplicationFolderPath 
    { 
        get { return Path.Combine(CompanyFolderPath, applicationFolder); }
    }
    /// <summary>
    /// Gets the path of the company's data folder.
    /// </summary>
    public string CompanyFolderPath 
    { 
        get { return Path.Combine(directory, companyFolder); }
    }
 
    private void CreateFolders(bool allUsers) 
    {
        DirectoryInfo directoryInfo;
        DirectorySecurity directorySecurity;
        AccessRule rule;
        SecurityIdentifier securityIdentifier = new SecurityIdentifier
            (WellKnownSidType.BuiltinUsersSid, null);
        if (!Directory.Exists(CompanyFolderPath))
        {
            directoryInfo = Directory.CreateDirectory(CompanyFolderPath);
            bool modified;
            directorySecurity = directoryInfo.GetAccessControl();
            rule = new FileSystemAccessRule(
                    securityIdentifier,
                    FileSystemRights.Write |
                    FileSystemRights.ReadAndExecute |
                    FileSystemRights.Modify,
                    AccessControlType.Allow);
            directorySecurity.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
            directoryInfo.SetAccessControl(directorySecurity);
        }
        if (!Directory.Exists(ApplicationFolderPath))
        {
            directoryInfo = Directory.CreateDirectory(ApplicationFolderPath);
            if (allUsers)
            {
                bool modified;
                directorySecurity = directoryInfo.GetAccessControl();
                rule = new FileSystemAccessRule(
                    securityIdentifier,
                    FileSystemRights.Write |
                    FileSystemRights.ReadAndExecute |
                    FileSystemRights.Modify,
                    InheritanceFlags.ContainerInherit |
                    InheritanceFlags.ObjectInherit,
                    PropagationFlags.InheritOnly,
                    AccessControlType.Allow);
                directorySecurity.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
                directoryInfo.SetAccessControl(directorySecurity);
            }
        }
    }
    /// <summary>
    /// Returns the path of the application's data folder.
    /// </summary>
    /// <returns>The path of the application's data folder.</returns>
    public override string ToString() 
    { 
        return ApplicationFolderPath;
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

DaveyM69
CEO Dave Meadowcroft
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberDidiKunz1-Jul-13 0:14 
Questionthis flag: PropagationFlags.InheritOnly is not enough PinmemberTCDooM2-Aug-11 3:53 
AnswerRe: this flag: PropagationFlags.InheritOnly is not enough PinmentorDaveyM693-Aug-11 13:02 
GeneralRe: this flag: PropagationFlags.InheritOnly is not enough Pinmemberpcbbc24-Jan-12 2:50 
GeneralRe: this flag: PropagationFlags.InheritOnly is not enough PinmemberSascha Nitschke12-Feb-13 14:47 
GeneralRe: this flag: PropagationFlags.InheritOnly is not enough PinmentorDaveyM6913-Feb-13 0:14 
QuestionPlease help PinmemberJigneshSE3-Jun-11 3:35 
AnswerRe: Please help PinmentorDaveyM693-Jun-11 9:36 
GeneralRe: Please help PinmemberJigneshSE3-Jun-11 19:49 
GeneralRe: Please help PinmentorDaveyM694-Jun-11 4:27 
GeneralRe: Please help PinmemberJigneshSE8-Jun-11 1:26 
General"Whilst I understand the reasoning for this" PinmemberQwertie26-Nov-10 9:55 
GeneralRe: "Whilst I understand the reasoning for this" PinmvpDaveyM6927-Nov-10 1:46 
GeneralApplication.CommonAppDataPath PinmemberAmir_Saniyan29-Sep-10 22:06 
GeneralRe: Application.CommonAppDataPath PinmvpDaveyM6930-Sep-10 11:02 
GeneralDoes not work on non english OS... Pinmembereric.ducos1-Mar-10 21:28 
GeneralFixed: Does not work on non english OS... [modified] PinmvpDaveyM692-Mar-10 10:27 
GeneralRe: Does not work on non english OS... Pinmemberwout de zeeuw16-Jun-10 2:19 
GeneralRe: Does not work on non english OS... PinmvpDaveyM6916-Jun-10 3:00 
GeneralRe: Does not work on non english OS... Pinmemberwout de zeeuw16-Jun-10 3:39 
Generalgreat PinmvpLuc Pattyn28-Feb-10 13:01 
GeneralRe: great PinmvpDaveyM6928-Feb-10 15:25 
GeneralRe: not great; excellent PinmvpLuc Pattyn28-Feb-10 15:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140926.1 | Last Updated 22 May 2010
Article Copyright 2010 by DaveyM69
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid