在Windows上保存依赖于机器(非用户)的ini文件的位置

时间:2009-08-11 02:05:03

标签: windows delphi delphi-7 environment

我的应用程序当前将设置存储在当前用户配置文件(WinXP下的C:\Documents and Settings\<CurrentUser>\Application Data\MyApplication\MySettings.ini)下的INI文件中。但我已经意识到其中一些设置对于机器而言不是用户所特有的,因此希望(实际上需要)将它们保存在所有用户的单个位置。

Windows XP(及更高版本)上是否有文件夹位置可以存储用户独立设置?

注意:我不想将它们存储在与我的应用程序相同的文件夹中,也不想将它们存储在注册表中。

我注意到“C:\ Documents and Settings \”下有“所有用户”文件夹?我应该在那里存储吗?

奖励积分:我更有可能将答案授予任何能告诉我如何在Delphi 7中从Windows返回此路径的人。

2 个答案:

答案 0 :(得分:12)

对于XP,Windows提供SHGetFolderPath()来获取已知位置。您正在寻找的CSIDL是CSIDL_COMMON_APPDATA,描述为:

  

包含所有用户的应用程序数据的文件系统目录。典型路径为"C:\Documents and Settings\All Users\Application Data"。此文件夹用于非用户特定的应用程序数据。例如,应用程序可以在CSIDL_COMMON_APPDATA文件夹中存储拼写检查字典,剪贴画数据库或日志文件。此信息不会漫游,并且可供使用该计算机的任何人使用。

对于Vista及更高版本,虽然SHGetFolderPath()仍可作为包装函数使用,但已被SHGetKnownFolderPath()取代。如果您使用真正的Vista通话,则应使用FOLDERID_ProgramData代替CSIDL_COMMON_APPDATA

此链接here似乎显示了这样做的方法。

似乎归结为这个(谨慎对待这个,我不熟悉德尔福):

function ShGetKnownFolderPath (
    const rfid:   TGUID;
    dwFlags:      DWord;
    hToken:       THandle;
    out ppszPath: PWideChar): HResult;
var
    Shell: HModule;
    Fn: TShGetKnownFolderPath;
begin
    Shell := LoadLibrary ('shell32.dll');
    Win32Check(Shell <> 0);
    try
        @Fn := GetProcAddress (Shell, 'SHGetKnownFolderPath');
        Win32Check (Assigned (Fn));
        Result := Fn (rfid, dwFlags, hToken, ppszPath);
    finally
        FreeLibrary (Shell);
    end;
end;

function GetKnownFolderPath (
    const rfid: TGUID;
    dwFlags:    DWord;
    hToken:     THandle): WideString;
var
    buffer: PWideChar;
    ret: HResult;
begin
    ret :=ShGetKnownFolderPath (rfid, dwFlags, hToken, buffer);
    OleCheck (ret);
    try
        Result := buffer;
    finally
        CoTaskMemFree (buffer);
    end;
end;

This page提供了所有CSIDL_*FOLDERID_*值的列表。请注意,您应该将这些功能用于特定于用户的数据,而不是像"C:\Documents and Settings\<CurrentUser>\Application Data\"这样的硬编码值。可能是Windows的不同语言版本使用不同的目录名称,或者用户可以自由移动其数据区域。

答案 1 :(得分:6)

我建议使用开源JEDI Code Library来做这类事情。

在JclShell.pas中,您将找到GetSpecialFolderLocation()

YourDataFolder := GetSpecialFolderLocation(CSIDL_COMMON_APPDATA);

它是免费的,经过良好测试,适用于所有Windows版本,并且使用它将使您免受未来对Windows API的更改。