views:

210

answers:

5

Hello, in my application I need to store settings that are 'global' (i.e. not user specific) in a known and predictable location.

I want the application to be able to be run from anywhere (as a standard user, NOT administrator), including multiple copies from different locations and be able to read and write the saved config files.

The data needs to have read and write access granted for ALL standard users, not just one.

With that in mind, the four options noted here are inappropriate: http://msdn.microsoft.com/en-us/library/bb206295%28VS.85%29.aspx#ID0E1BA

So what are my alternatives?

My application is written in C++ and for Windows only. I need to support Windows XP and above.

Thanks.

EDIT:

To clarify, ignore race conditions caused by multiple instances. This question is solely to do with WHERE TO STORE THE DATA. I can't see anywhere suitable that is:

  1. Predictable (e.g. %APPDATA%\Foo is a 'predictable' path, but unfortunately user-specific)
  2. Global (e.g. %PROGRAMDATA%\Foo is a global path but unfortunately only the creating user has write-access)
  3. Accessible (a standard user needs to be able to create new files in the given directory, this applies to all users on the system)
A: 

options:

  1. File Mutex to control access to the file
  2. Database to store settings
  3. Web Service to store settings which can handle concurrency
tster
My problem is not do to with synchronization, but rather to do with the fact I can't find somewhere global that a non-admin can actually write data.
RaptorFactor
+1  A: 

Try the Public folder in the user profiles directory:

CSIDL_COMMON_DOCUMENTS

Edit: Or do use

CSIDL_COMMON_APPDATA

but set the permissions to the Authenticated Users group if possible.

ZippyV
+1  A: 

You're probably looking for CSIDL_COMMON_APPDATA. IIRC that should also be a good choice should you go for any of Windows logo certifications. In case it doesn't fit your requirements, check this link on MSDN, you should be able to find the best fit for your needs there.
Good luck.

Dmitry
BTW: you should avoid storing any sensitive user data in that directory.
Dmitry
+1  A: 

Can you not just use a fixed directory name, e.g. c:\FixedDataForYourProgram

We do this on XP. I've not tried this programmatically on Vista/Win7, but logged in as a standard user on Vista I have no problem creating a directory under root.

I'm sure this breaks all sorts of rules, but it is simple. I like simple.

IanH
Simple... and messy. It makes it harder for the application to still work across user-state migration, in the presence of roaming user profiles, etc.
Reuben
But the question wants a fixed location. This meets the stated requirements (predictable/global/accessible). Too much effort goes on solving problems that never arise.
IanH
+2  A: 

If you decide that CSIDL_COMMON_APPDATA isn't appropriate (maybe CSIDL_COMMON_APPDATA is a good default, but you want the administrator to be able to change the location) you can have the installer write something to an HKLM\SOFTWARE\<your app subkey> that indicates the desired path for the common directory that will hold the data.

An alternative to placing the pointer in the HKLM registry is to have a config file that resides in the program directory which has a pointer to the shared directory. By definition the program directory must writable by the installer, it's writable by administrators (who might be responsible for modifying the configuration), and it's readable by users. So a standard user can read a well-known location (either an HKLM sub-key or a config file in the program directory) to get a pointer to a directory that's writable by all standard users.

Whatever sets up the common directory (the install program or the configuration module) will need to make sure the common directory's ACL is set appropriately for standard user writes.

Michael Burr
"you can have the installer write something to an HKLM\SOFTWARE\<you app subkey>"I've done this in widely distributed desktop applications. I have the installer give standard user permissions to write to this key.
Jim In Texas
@Jim: I didn't mention setting the ACL for an HKLM subkey to something writeable by standard users (which could also be done for a sub-directory of the program directory) because I think it's generally considered bad practice (though I'm not sure I agree). I thought it might also be a problem with logo certification, though I don't know if that's correct or not.
Michael Burr