Where to save ini file dependent to machine (not user) on windows

走远了吗. 提交于 2019-12-04 08:39:35

For XP, Windows provides SHGetFolderPath() to get a known location. The CSIDL that you're looking for is CSIDL_COMMON_APPDATA, described as:

The file system directory that contains application data for all users. A typical path is "C:\Documents and Settings\All Users\Application Data". This folder is used for application data that is not user specific. For example, an application can store a spell-check dictionary, a database of clip art, or a log file in the CSIDL_COMMON_APPDATA folder. This information will not roam and is available to anyone using the computer.

For Vista and later, this has been replaced with SHGetKnownFolderPath() although SHGetFolderPath() is still available as a wrapper function for that. If you use the real Vista call, you should use FOLDERID_ProgramData instead of CSIDL_COMMON_APPDATA.

This link here seems to show a way of doing it.

It seems to boil down to this (treat this with circumspection, I don't know Delphi that well):

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 provides a list of all the CSIDL_* and FOLDERID_* values. Keep in mind you should be using these functions for your user-specific data as well, not hard-coded values like "C:\Documents and Settings\<CurrentUser>\Application Data\". It may be that different language versions of Windows use different directory names or it's possible that users can freely move their data areas around.

I'd recommend using the open source JEDI Code Library for this sort of thing.

In JclShell.pas you'll find GetSpecialFolderLocation()

YourDataFolder := GetSpecialFolderLocation(CSIDL_COMMON_APPDATA);

It's free, well tested, works with all Windows versions and using it will insulate you from future changes to the Windows API.

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