0

I have a file called middle.config that is deployed in the same directory as an exe, but I need to update values in this file. That means that I have to go to C:\Program Files (x86)\ directory to access the file. Although it is named as a .config file it does not follow the usual schema of a .config file. It looks like this:

<configuationSettings>     
  <middleSettings      
   groupName="XYZ"     
   forkName="SomeDbName"     
   dbServerName="123.123.123.123"     
   cnnTimeoutSeconds="30"     
   cmdDefaultTimeoutSeconds="30"     
   cmdMediumTimeoutSeconds="60"     
   cmdLongTimeoutSeconds="480"     
   />     
 <userKeys>     
   <Assemblies value="C:\assemblies\" />     
 </userKeys>     
 <friendlyDbName value="NiceData"/>     
</configuationSettings>     

I'm able to read and manipulate the content with Xml, but when I try to save the file back, a "No Permissions" error is thrown. I cannot relocate the file. I'm stuck with this legacy schema so I'm not able to treat it like a normal .config file using ConfigurationManager.OpenExeConfiguration. I cannot define sections or groups on this schema (I've not been able to anyway). All my users are Administrators on their local machines.

How do I overwrite or delete and replace this file while it is in a protected directory(my assumption about the permissions error)? Failing that, is there a way to access this schema somehow with ConfigurationManager.OpenExeConfiguration.

{edit starts here}

There are three applications in this scenario, A, B, and mine C. Application A does not know about any other applications. It can connect to many, many databases, and it drops a single file 'middle.config' that contains pointer info to the last database location that was used by the last Application A session. Application B, let's call it an import/export application, only operates on the last Application A database location. Application B reads the 'middle.config' file for database pointer info and then executes console commands against that database. It performs bulk dumps or bulk imports for selected portions of the database.

This was the situation when I come along to build application C that uses the import/export application B to fetch, blocks of data and return them to the database. So, in order for application C to use Application B against any database, application C must modify the 'middle.config' file so that application B will find the correct database. Application C is new and the other two are legacy. I either find a way to make this work, or I force the user to start Application A and point to the database of interest, then close Application A. This is VERY unhandy.

{edit ends here}

JimBoone
  • 554
  • 1
  • 7
  • 27

5 Answers5

3

It is not advisable to write data files to the program files directory, as this requires elevated permissions. Giving a program elevated permissions just to update a config file clashes with the Principal of Least Privilege, which states that

a particular abstraction layer of a computing environment, every module (such as a process, a user or a program depending on the subject) must be able to access only the information and resources that are necessary for its legitimate purpose

It's not a "legitimate purpose" to give the process elevated permissions (that can allow it to do many harmful things) just to update a config file. MS recommended practice is to write that type of data elsewhere.

Instead, consider storing the config file in a subfolder of the ApplicationData folder.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • I agree with the ideology, but I don't have a choice in the matter. This is a legacy app and I need to modify this file to get my app to work. – JimBoone Jun 08 '12 at 18:06
  • @JimBoone: In that case, you can either a) Do something to modify the permissions of that specific config file (recommended... perhaps once-off "repair" program, or perhaps just instruct the user on how to do it); or b) Run your program with elevated permissions (less desirable) – Eric J. Sep 04 '12 at 15:27
0

Your assumption about protected directories is correct. Program Files has an Access Control List which prevents modification by processes running as standard users and, on Vista upwards, even by administrator processes which are not running elevated. Accessing the file using the standard configuration classes would not get around this.

If you absolutely can't move the file (Eric J. is right when says that writing to Program Files after installation is a bad idea), then you could embed a manifest in your config file-editing program which will try to force elevation with a UAC prompt at launch. Of course, the best solution would involve a) using standard config schema and b) keeping user data in user-writeable locations, but sometimes that isn't possible for legacy reasons.

I'm not aware of any way to persuade ConfigurationManager to read a non-standard schema, unfortunately.

Community
  • 1
  • 1
anton.burger
  • 5,637
  • 32
  • 48
  • So, if the app had elevated permissions, it could write to the Program directory? – JimBoone Jun 08 '12 at 18:45
  • Yes. Makubex's suggestion of a separate privileged component which runs only those parts which need elevation is a better solution, but needs some design consideration about how to handle the inter-process communication, and preferably only prompt for elevation once, rather than every time you save. – anton.burger Jun 15 '12 at 08:50
0

Suggested that your app is creating its own location under the AppData location folder for the current user instead of writing to files under location where the the app is installed (especially if under Program Files which is very strict.) Not suggested to force the user to run as Administrator for your application either.

Quintium
  • 499
  • 5
  • 22
0

Move the logic to a separate process and launch it with admin privileges from your current application.

Makubex
  • 1,054
  • 1
  • 9
  • 16
  • Say a little more about the concept. Do you mean "isolate the raised privileges" in a separate process? – JimBoone Jun 08 '12 at 18:42
  • Yes. It's not a good practice to elevate your whole app just for this. Instead move the parts which manage this config file to another console app - this can be executed with Admin rights. But note, it will probably pop-up UAC dlg box to the user – Makubex Jun 08 '12 at 19:15
  • Thanks, I'll have to give it a try first. If it works, this will be the answer. I'll know in a couple of weeks ( delivery commitments in the way right now ). – JimBoone Jun 08 '12 at 21:25
0

From a different angle, look at this: Writing custom sections into app.config

I found the linked article to be very useful. Not sure it is going to answer all your questions though.

Community
  • 1
  • 1
Trey Gramann
  • 2,004
  • 20
  • 23