Usage of SHGetSpecialFolderPath to retrieve an application folder that can be accessed also to non admin users, which CSIDL to choose?

LaBracca picture LaBracca · Feb 23, 2011 · Viewed 13.3k times · Source

In my application I store on every machine some files in an application folder.

A simplified version of the real case is this:

..\Project1\LoginHistory (login history file - common for all users)
..\Project1\Translations (localization files - common for all users)
..\Project1\FormSettings\User1\ (this contains an ini file per form for User1)
..\Project1\FormSettings\UserN\ (this contains an ini file per form for UserN)

So you can see why I use this: to save some data that is specific to the machine (remember the latest logins made from this machine, a kind of MRU), to store Translation strings or 3rd party components (these are extracted runtime from exe resources) and for saving some user specific data (like form size). The real case is more complex, but at least you can get that there are some "common folder" and some "user folders".

Now I would like to keep this structure, so all my files in a single ..\Project1 folder (+ subfolders). Even because the users are not the windows users, but they are SQL Server users.

My question is which folder to choose for ..\.

Currently I am (succesfully) using this code for retrieveing ..\

uses ShlObj;

function GetSpecialFolder(const CSIDL: integer) : string;
var
  RecPath : PWideChar;
begin
  RecPath := StrAlloc(MAX_PATH);
    try
    FillChar(RecPath^, MAX_PATH, 0);
    if SHGetSpecialFolderPath(0, RecPath, CSIDL, false) 
      then result := RecPath
      else result := '';
    finally
      StrDispose(RecPath);
    end;
end;

And I call it with

GetSpecialFolder(CSIDL_APPDATA)

Where the list of CDISL is defined here.

GetSpecialFolder(CSIDL_APPDATA) returns C:\Users\username\AppData\Roaming in Windows 7.

So this used to work, but recently I recieved some complaint from some customer that seems directly related to read/write problems in these folders. (for example C:\Users\username\AppData\Roaming\Project1\LoginHistory - using folders listed above).

So my question is: is it correct to use CSIDL_APPDATA? Do you have another suggestion? Is there a chance that on some OS or with some users with really reduced privileges there can be read/write problems on that folder?

Please remember that I would not like to have more than one root folder for my files.

Answer

Argalatyr picture Argalatyr · Feb 23, 2011

I think you want to use CSIDL_COMMON_APPDATA for files that are not user-specific. If you assumed (in your code) that files stored in CSIDL_APPDATA are shared among users, that is not allowed.