Question

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(VS.85).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)
Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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.

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top