使用SHGetSpecialFolderPath来检索可以访问非管理员用户的应用程序文件夹,CSIDL可以选择哪个?

时间:2011-02-23 10:51:08

标签: delphi winapi special-folders

在我的应用程序中,我将每个机器上的一些文件存储在应用程序文件夹中。

真实案例的简化版本是:

..\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)

所以你可以看到我使用它的原因:保存一些特定于机器的数据(记住从这台机器做的最新登录,一种MRU),以存储翻译字符串或第三方组件(这些是提取的来自exe资源的运行时)以及用于保存一些用户特定数据(如表单大小)。真实案例更复杂,但至少你可以得到一些“公共文件夹”和一些“用户文件夹”。

现在我想保留这个结构,所以我的所有文件都在一个.. \ Project1文件夹(+子文件夹)中。即使因为用户不是Windows用户,也是SQL Server用户。

我的问题是为..\选择哪个文件夹。

目前我(已成功)使用此代码检索..\

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;

我用

来称呼它
GetSpecialFolder(CSIDL_APPDATA)

定义CDISL列表here

GetSpecialFolder(CSIDL_APPDATA)在Windows 7中返回C:\Users\username\AppData\Roaming

所以这曾经有用,但最近我收到了一些客户的投诉,这些投诉似乎与这些文件夹中的读/写问题直接相关。 (例如C:\Users\username\AppData\Roaming\Project1\LoginHistory - 使用上面列出的文件夹。)

所以我的问题是:使用CSIDL_APPDATA是否正确?你还有其他建议吗?是否有可能在某些操作系统或某些具有真正降低权限的用户上,该文件夹上可能存在读/写问题?

请记住,我不希望我的文件有多个根文件夹。

2 个答案:

答案 0 :(得分:5)

我认为您希望将CSIDL_COMMON_APPDATA用于非特定于用户的文件。如果您(在您的代码中)假设存储在CSIDL_APPDATA中的文件在用户之间共享,则不允许这样做。

答案 1 :(得分:0)

我最终使用的方法是正确的。因为我并不真的需要我的应用程序的公共文件(所有临时文件都是特定于用户的 - 因为数据库中存储了一些常见的东西)CSIDL_APPDATA是一个好地方。

我遇到的问题仍然不明确,但我怀疑这是因为login.ini是一个保留字(仅在最近一些最近的Windows更新之后)。

我已经问过this question