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

走远了吗. 提交于 2019-12-07 00:45:47

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/5089877/usage-of-shgetspecialfolderpath-to-retrieve-an-application-folder-that-can-be-ac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!