SHGetSpecialFolderLocation是否有新的替代品?

时间:2019-01-21 20:20:55

标签: c++ winapi

我的应用程序是用C ++ Builder for Win32编写的。我的代码使用SHGetSpecialFolderLocation() API来获取CSIDL_APPDATACSIDL_MYDOCUMENTS路径。

我在2018年12月4日的Microsoft网站上注意到它说:

  

[SHGetSpecialFolderLocation不支持,将来可能会更改或不可用。而是使用SHGetFolderLocation。]

然后SHGetFolderLocation说:

  

已弃用

获取这两条路径的当前方法是什么?

我当前的代码如下。

LPITEMIDLIST List = NULL;
wchar_t  wPath[MAX_PATH + 1];
UnicodeString S01, Fi;

if( !SHGetSpecialFolderLocation(0, CSIDL_APPDATA, &List) ){
  if( SHGetPathFromIDListW(List, wPath ) ){
    S01 = wPath;
    Fi = (S01+"\\my_files\\");
    Form1->MyRoamingPath_Mh = Fi;
  }
}

1 个答案:

答案 0 :(得分:9)

SHGetSpecialFolderLocation()最初是在Windws 95 / NT4中引入的。在Windows 2000 / XP中,不推荐使用它,而推荐使用SHGetFolderLocation()(将文件夹位置作为IDLIST_ABSOLUTE返回)和SHGetFolderPath()(将文件夹位置作为路径字符串返回)。

因此,在您的示例中,您可以改用SHGetFolderPath()

#include <Shlobj.h>
#include <SysUtils.hpp>

wchar_t wPath[MAX_PATH + 1];

if (SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wPath) == S_OK)
{
    Form1->MyRoamingPath_Mh = IncludeTrailingPathDelimiter(wPath) + L"my_files\\";
}

在Vista中,不推荐使用CSIDL,而推荐使用KNOWNFOLDERID。不推荐使用上述功能,而分别推荐使用SHGetKnownFolderIDList() / IKnownFolder::GetIDList()SHGetKnownFolderPath() / IKnownFolder::GetPath()

实际上是在SHGetFolderLocation()文档 1 底部中声明的:

1:我想您没有向下滚动足够远才能看到它。

  

注意从Windows Vista开始,此功能仅是SHGetKnownFolderIDList的包装。将CSIDL的值转换为与其关联的KNOWNFOLDERID,并调用SHGetKnownFolderIDList新应用程序应使用已知的文件夹系统,而不是较旧的CSIDL系统,该系统仅出于向后兼容的目的而受支持

因此,在您的示例中,您现在可以改为使用SHGetKnownFolderPath()

#include <Shlobj.h>
#include <SysUtils.hpp>

PWSTR pwPath;

if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, NULL, &pwPath) == S_OK)
{
    try
    {
        Form1->MyRoamingPath_Mh = IncludeTrailingPathDelimiter(pwPath) + L"my_files\\";
    }
    __finally
    {
        CoTaskMemFree(pwPath);
    }
}

对于“我的文档”文件夹,使用FOLDERID_Documents