views:

42

answers:

2

I am using ClickOnce deployment for a Windows Forms application and I need configuration information on a machine basis that persists across deployments and across user profiles. As such, per user configuration does not help. I would also like the configuration file to be easily accessible with a text editor in a well known location on each machine (well known, that is, by the organization).

The problem I have is that ClickOnce overwrites the app.config on each deployment. I am aware of the configsource attribute, but from what I understand, the target file has to be in the path of the application - that means that I can't control the location effectively.

So I created a class for the data I want to persist and am serializing / deserializing it to and from the location I want. This all works well, except that if the file doesn't exist I am creating it (using XmlSerializer and a TextWriter). The problem here is that the user that is running the app when it is created becomes the only user that can access it. Subsequent users do not have permission unless I grant permission to a broader AD group manually. Even this is fine except for the fact that I don't want to touch each computer the first time it is installed.

So is there a good way to programatically set permissions when the file is created or should I re-think my design because I have missed something about the built in configuration features?

EDIT: Looked in to Application.CommonAppDataPath, but it maintains a folder for each version of the application which means that each new deployment is starting over.

+1  A: 

IIRC, You can reference the All Users Application Data folder in click once apps.

What you do is distribute your default configuration to the normal application data folder for each app, but never read config information from that file. Instead, on app startup you look in your All users application data folder for the config file, and if you don't find it copy the default file there. Then read in your config from that location.

Joel Coehoorn
Thanks Joel - I didn't completely test your solution by running as different users, but I did copy my file to All Users\Application Data and then looked at the security settings for it and it was the same as what I was seeing in other, non-Application Data, folders. That is, the user that created it has full control but nothing obvious that would give other users control. Maybe giving other users control is baked in to Application Data? I ended going with explicitly granting the built in Users group full control.
MarkB
@MarkB - make sure you use the .net `Environment` object and it's `SpecialFolder` enum to make sure you're going to the right place in the right way. The nature of the All Users folder is that if permissions are inherited from the folder (and they should be) everyone should have write access. The first user will also have extra ownership permissions, but that won't stop things from working.
Joel Coehoorn
Also - I see your note about commonappdata getting a new folder per update. That might be trickier, but there ought to be something in app data that's accessible to all versions.
Joel Coehoorn
@Joel, I thought about putting the file up one level from the version folder in app data (which is the product name folder). The inheritance is a good point so that might work. For now though, I am going to go with explicitly setting permissions for the Users group because the other issue is that this company already has a convention of putting the config files in specific folder under c:\, so this way I can also maintain their standard.
MarkB
A: 
MarkB