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

发布于 2024-10-19 07:54:58 字数 1673 浏览 2 评论 0原文

在我的应用程序中,我在每台计算机上的应用程序文件夹中存储一些文件。

真实案例的简化版本是这样的:

..\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),存储翻译字符串或3rd 方组件(这些是从 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 列表”此处

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

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

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合约呢 2024-10-26 07:54:58

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

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.

墨小沫ゞ 2024-10-26 07:54:58

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

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

我已经问过这个问题

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文