Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS2008 Setup Project: Shared (By All Users) Application Data Files?

fellow anthropoids and lily pads and paddlewheels!

I'm developing a Windows desktop app in C#/.NET/WPF, using VS 2008. The app is required to install and run on Vista and XP machines. I'm working on a Setup/Windows Installer Project to install the app.

My app requires read/modify/write access to a SQLCE database file (.sdf) and some other database-type files related to a third-party control I'm using. These files should be shared among all users/log-ins on the PC, none of which can be required to be an Administrator. This means, of course, that the files can't go in the program's own installation directory (as such things often did before the arrival of Vista, yes, yes!).

I had expected the solution to be simple. Vista and XP both have shared-application-data folders intended for this purpose. ("\ProgramData" in Vista, "\Documents and Settings\All Users\Application Data" in XP.) The .NET Environment.GetFolderPath(SpecialFolder.CommonApplicationData) call exists to find the paths to these folders on a given PC, yes, yes!

But I can't figure out how to specify the shared-application-data folder as a target in the Setup project.

The Setup project offers a "Common Files" folder, but that's intended for shared program components (not data files), is usually located under "\Program Files," and has the same security restrictions anything else in "\Program files" does, yes, yes!

The Setup project offers a "User's Application Data" folder, but that's a per-user folder, which is exactly what I'm trying to avoid, yes, yes!

Is it possible to add files to the shared-app-data folder in a robust, cross-Windows-version way from a VS 2008 setup project? Can anyone tell me how?

like image 263
Lyman Enders Knowles Avatar asked Sep 16 '08 20:09

Lyman Enders Knowles


People also ask

How to create a project in Visual Studio 2010?

In the add new project dialog box select "Setup and Deployment" from other project types and then select Setup Project. In the setup project file system editor window, right-click on the Application folder then select "Add" > "Project Output". Now select primary output from the next dialog box and click on OK.

How to deploy a Windows application using ClickOnce (Visual Studio 2008)?

Right-click on the user's Desktop and create a shortcut to primary output in the application folder. Similarly add a shortcut in the user's Program Menu. Build the project by right-clicking on the setup project name and run the setup. Deploying Windows applications using ClickOnce (Visual Studio 2008)

How to add special folders to a setup project?

1) Select a SetUp Project type as shown in Display 1. 2) The default File System editor will appear in the window as shown in Display 2. 3) One can add special folders here into which they intend to add files. Just right click on the editor to view the special folder types available.

How to create a setup project for a Windows/web application?

A similar approach can be applied for creating a setup project for web applications as well. First of all create a sample Windows/web application. Right-click on Solution Explorer root and select "Add" > "New project". In the add new project dialog box select "Setup and Deployment" from other project types and then select Setup Project.


Video Answer


2 Answers

I have learned the answer to my question through other sources, yes, yes! Sadly, it didn't fix my problem! What's that make me -- a fixer-upper? Yes, yes!

To put stuff in a sub-directory of the Common Application Data folder from a VS2008 Setup project, here's what you do:

  1. Right-click your setup project in the Solution Explorer and pick "View -> File System".

  2. Right-click "File system on target machine" and pick "Add Special Folder -> Custom Folder".

  3. Rename the custom folder to "Common Application Data Folder." (This isn't the name that will be used for the resulting folder, it's just to help you keep it straight.)

  4. Change the folder's DefaultLocation property to "[CommonAppDataFolder][Manufacturer]\[ProductName]". Note the similarity with the DefaultLocation property of the Application Folder, including the odd use of a single backslash.

  5. Marvel for a moment at the ridiculous (yet undeniable) fact that there is a folder property named "Property."

  6. Change the folder's Property property to "COMMONAPPDATAFOLDER".

Data files placed in the "Common Application Data" folder will be copied to "\ProgramData\Manufacturer\ProductName" (on Vista) or "\Documents and Settings\All Users\Application Data\Manufacturer\ProductName" (on XP) when the installer is run.

Now it turns out that under Vista, non-Administrators don't get modify/write access to the files in here. So all users get to read the files, but they get that in "\Program Files" as well. So what, I wonder, is the point of the Common Application Data folder?

like image 180
Lyman Enders Knowles Avatar answered Oct 19 '22 05:10

Lyman Enders Knowles


Instead of checking "Enable ClickOnce Security Settings" and selecting "This is a full trust application", it is possible to change the permissions of your app's CommonAppDataDirectory with a Custom Action under the "install" section of a setup project. Here's what I did:

  1. Added a custom action to call the app being installed (alternately you could create a separate program/dll and call that instead)
  2. Set the Arguments property to "Install"
  3. Modified Main in Program.cs to check for that arg:

    static void Main(string[] args) { if (args != null && args.Length > 0 && args[0] == "Install") { ApplicationData.SetPermissions(); } else { // Execute app "normally" } }
  4. Wrote the SetPermissions function to programmatically change permissions

    public static void SetPermissions() { String path = GetPath(); try { // Create security idenifier for all users (WorldSid) SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); DirectoryInfo di = new DirectoryInfo(path); DirectorySecurity ds = di.GetAccessControl(); // add a new file access rule w/ write/modify for all users to the directory security object
    ds.AddAccessRule(new FileSystemAccessRule(sid, FileSystemRights.Write | FileSystemRights.Modify, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, // all sub-dirs to inherit PropagationFlags.None, AccessControlType.Allow)); // Turn write and modify on // Apply the directory security to the directory di.SetAccessControl(ds); } catch (Exception ex) { MessageBox.Show(ex.Message); } }

Since the installer runs with admin rights, the program will be able to change the permissions. I read somewhere that the "Enable ClickOnce Security" can cause the user to see an undesired prompt at app startup. Doing it as described above will prevent this from happening. I hope this helps someone. I know I could have benefited from seeing something like this a few days ago!

like image 10
ejwipp Avatar answered Oct 19 '22 07:10

ejwipp