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.

2

There are 2 answers

0
UnDiUdin On BEST ANSWER

The approach I use finally is correct. Since I do not really need common files for my application (it makes sense that all the temp files are user specific - because the few common things are stored in the DB) CSIDL_APPDATA is a good place.

The problem I was facing it is still not clear but I suspect it is due to the fact that login.ini is a reserved word (only recently, after some recent windows update maybe).

I already asked this question.

7
Argalatyr On

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.