Using SHGetSpecialFolderPath to retrieve an application folder that can also be accessed by non-admin users who select CSIDL?

In my application, I store on each machine some files in the application folder.

A simplified version of the real case is as follows:

..\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 understand why I use this: to save some machine-specific data (remember the last logins made from this device, a kind of MRU), to store translation strings or third-party components (they are extracted from the exe resources) and to save some user data (e.g. form size). The real case is more complicated, but at least you can get that there is a "public folder" and some "user folders".

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

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

I am currently (successfully) using this code to retrieve ..\

 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

 GetSpecialFolder(CSIDL_APPDATA) 

Where the CDISL list is defined here .

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

So it worked, but recently I received some complaint from some client who seems to be directly related to read / write problems in these folders. (for example, C:\Users\username\AppData\Roaming\Project1\LoginHistory - using the folders listed above).

So my question is: is it correct to use CSIDL_APPDATA ? Do you have another suggestion? Is there any chance that on any OS or with some users with really reduced privileges in this folder there may be problems with reading / writing?

Remember that I would not want to have more than one root folder for my files.

+7
source share
2 answers

The approach that I use is finally correct. Since I really don't need shared files for my application (it makes sense that all temporary files are user-specific, because several common things are stored in the database) CSIDL_APPDATA is a good place.

The problem that I encountered is still not clear, but I suspect that this is because login.ini is a reserved word (only recently, after some recent Windows update).

I already asked this question .

0
source

I think you want to use CSIDL_COMMON_APPDATA for files that are not user dependent. If you assumed (in your code) that the files stored in CSIDL_APPDATA are shared by users, this is unacceptable.

+5
source

All Articles