1

I have created an installer for a WPF application on "Visual Studio Installer" in Visual Studio 2017 Community Edition. In my application, there is a setting file which needs write permission as the settings changes during application running time.

I want to install my application in "Programe Files" folder but at the same time, I want to create a folder in "ProgramData" location to copy my setting file.

I am unable to create a folder and copy the file to "ProgramData" and I have gone through many resources but no luck at the end.

I found a relevant answer in the link here but it's related to Visual Studio 2010 and I didn't find the mentioned option [CommonAppDataFolder] in DefaultLocation in visual studio 2017.

Could you help me to achieve this goal? Thanks for helping.

Simant
  • 3,142
  • 4
  • 32
  • 61

2 Answers2

0

Though this option is not available in the DefaultLocation ComboBox, you could manually give [CommonAppDataFolder] option. Once you give this option the Custom folder will be copied to the ProgramData folder.

But the folder or files created this way are only Read-only permission. To make the folder/files writeable permission as well, I used alternate approach. I used installer file instead of the above. Below is the code sample to give folder and files full access control.

    [RunInstaller(true)]
    public partial class Installer1 : Installer
    {
        private string fullPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\YourFolder";

        public override void Install(IDictionary savedState)
        {
            base.Install(savedState);
            //Add custom code here


            if (!Directory.Exists(fullPath))
            {
                Directory.CreateDirectory(fullPath);

                // Create files on inside the folder to make them writable
                   ... 
            }

            // https://stackoverflow.com/questions/9108399/how-to-grant-full-permission-to-a-file-created-by-my-application-for-all-users

            DirectoryInfo dInfo = new DirectoryInfo(fullPath);
            DirectorySecurity dSecurity = dInfo.GetAccessControl();
            dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                                    FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
                                    PropagationFlags.NoPropagateInherit, AccessControlType.Allow));

            dInfo.SetAccessControl(dSecurity);
        }

        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
            //Add custom code here

            if (Directory.Exists(fullPath))
            {
                Directory.Delete(fullPath, true);
            }
        }

        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
            //Add custom code here
        }

        public override void Uninstall(IDictionary savedState)
        {
            Process application = null;
            foreach (var process in Process.GetProcesses())
            {
                if (!process.ProcessName.ToLower().Contains("yourprocessname"))
                    continue;
                application = process;
                break;
            }

            if (application != null && application.Responding)
            {
                application.Kill();
                base.Uninstall(savedState);
            }

            if (Directory.Exists(fullPath))
            {
                Directory.Delete(fullPath, true);
            }
        }
    }
Simant
  • 3,142
  • 4
  • 32
  • 61
  • Does this application of yours run with admin rights / elevation? I don't think the files in *CommonAppDataFolder* are writable for regular users? – Stein Åsmul Oct 03 '18 at 14:09
  • @SteinÅsmul Yes, you are right. I used a different approach and I have updated my answer too. Please share with me if you know a better approach. Thanks – Simant Oct 03 '18 at 14:31
0

Settings Files Templates: We tend to repeat this advice a lot, but any files you intend to modify during the operation of your application we recommend you dis-entangle from deployment concerns by installing read-only template files under ProgramFiles that your application makes copies of and then stores in the user profile. The setup will then never interfere with the files after they are created. No unexpected settings file wipe-out. In the user profile the files will have full write access.

Shared Settings File: If you want a single settings file shared by all users (in most cases a bad idea), you can copy it to the CommonAppDataFolder in a folder that you have opened for write access for regular users using ACL permissioning. Not great to do, but possible. In WiX, Advanced Installer and Installshield you can change ACLs as a built in feature, but you have made a custom action using the Visual Studio Installer project. OK, but please read these notes on limitations of Visual Studio Installer projects.

Relevant Links:

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164