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

LaB*_*cca 7 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)
Run Code Online (Sandbox Code Playgroud)

所以你可以看到我使用它的原因:保存一些特定于机器的数据(记住从这台机器制造的最新登录,一种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;
Run Code Online (Sandbox Code Playgroud)

我称之为

GetSpecialFolder(CSIDL_APPDATA)
Run Code Online (Sandbox Code Playgroud)

凡CDISL列表定义在这里.

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

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

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

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

Arg*_*tyr 5

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


LaB*_*cca 0

我最终使用的方法是正确的。由于我的应用程序实际上并不需要通用文件(所有临时文件都是用户特定的是有道理的 - 因为少数通用文件存储在数据库中)CSIDL_APPDATA是一个好地方。

我面临的问题仍然不清楚,但我怀疑这是由于 login.ini 是一个保留字(直到最近,可能是在最近的一些 Windows 更新之后)。

我已经问过这个问题了。