SHGetFolderPath 已弃用:检索 Windows 文件夹路径的替代方法是什么
SHGetFolderPath Deprecated: What is alternative to retrieve path for Windows folders?
从Windows Vista开始,SHGetFolderPath()
函数被弃用:http://msdn.microsoft.com/en-us/library/bb762181%28v=VS.85%29.aspx
在 Windows 中检索应用程序文件夹路径的替代方法是什么?
SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath)
除此之外,为什么我在使用此函数时会出现这些错误:
Error 1 error C2065: 'CSIDL_COMMON_APPDATA' : undeclared identifier
Error 2 error C3861: 'SHGetFolderPath': identifier not found
您链接到的文档中描述了替代方法。即它是SHGetKnownFolderPath
.
但是,SHGetKnownFolderPath
仅在 Vista 或更高版本上可用。因此,如果您使用加载时间链接,并运行在XP上调用SHGetKnownFolderPath
的程序,则该程序将无法启动。如果您希望支持XP,这显然是一个问题。
现在,您可以切换到SHGetKnownFolderPath
的运行时链接。在调用之前执行版本检查,如果函数不可用,则回退到SHGetFolderPath
。
就个人而言,我不会让这种弃用让您过度担心。Microsoft以保持向后兼容性而闻名。不要指望SHGetFolderPath
很快就会消失。你会发现SHGetFolderPath
存在于Windows 8中,我希望它仍然存在于10年后的任何Windows中。我的建议是坚持加载时间链接,只有在放弃支持 XP 时才切换到 SHGetKnownFolderPath
。
您在编辑中提出的另一个问题是如何调用SHGetFolderPath
.您需要遵守您在问题中链接到的 MSDN 文档主题底部列出的要求。具体而言,包括Shlobj.h
并将Shlobj.lib
传递给链接器。
它链接在顶部,SHGetKnownFolderPath。
CSIDL_COMMON_APPDATA在新 API 中替换为FOLDERID_ProgramData。
当我向已经工作的解决方案添加一些新的头文件时,我遇到了同样的一组错误。
我已经在调用SHGetFolderPath
并且还包含#include <ShlObj.h>
但它在不同的头文件中。解决方案是在我添加新的库头文件之前编译没有任何错误。
我尝试用SHGetKnownFolderPath()
替换SHGetFolderPath()
,但这只是将标识符未找到错误重定向到SHGetKnownFolderPath
。
在将
#include <ShlObj.h>
添加到调用SHGetFolderPath
的类的头文件时,将 错误停止,解决方案再次成功编译。
如本页所述,在 Windows Vista 或更高版本的操作系统上调用SHGetFolderPath
将在内部调用 SHGetKnownFolderPath
。
Windows 10 PC上使用Visual Studio 2015 Enterprise的SHGetFolderPath()
进行了测试,它编译并工作得很好,可以找到当前用户的主文件夹。在 Windows 开发人员中心页面SHGetFolderPath()
SHGetFolderPath 函数上有以下注释:
注意:从 Windows Vista 开始,此函数只是
SHGetKnownFolderPath
.CSIDL
值将转换为其关联的值KNOWNFOLDERID
然后调用SHGetKnownFolderPath
。新增功能 应用程序应使用已知的文件夹系统,而不是较旧的文件夹系统CSIDL
系统,仅支持向后兼容。
正如David Heffman在他的回答中指出的那样,Microsoft多年来一直保持向后兼容性,特别是当他们可以使用旧函数并将其重定向到具有适当参数的新函数时。CSIDL
值似乎具有相应的KNOWNFOLDERID
值。请参阅此表,其中包含带有简短注释和相应KNOWNFOLDERID
值的CSIDL
常量。
下面是使用该函数的示例。此用途检索当前用户的用户文件夹(例如 Windows 7 下的"C:\Users\myuser\Documents"(,然后使用 PathAppend()
函数将文件夹名称添加到路径末尾。
TCHAR achDevice[MAX_PATH];
HRESULT hr;
// include file ShlObj.h contains list of CSIDL defines however only a subset
// are supported with Windows 7 and later.
// for the 3rd argument, hToken, can be a specified Access Token or SSID for
// a user other than the current user. Using NULL gives us the current user.
if (SUCCEEDED(hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, achDevice))) {
// append a folder name to the user's Documents directory.
// the Path Handling functions are pretty handy.
PathAppend(achDevice, L"xxx");
}
一个可能的失败是一个或多个无效参数 (hr == E_INVALIDARG
(。返回值 S_OK
表示调用成功。
有一些CSIDL
常量可用于修改函数的结果,例如使用按位 OR 运算符修改CSIDL_FLAG_CREATE
。我不确定这些操作员在Windows 7及更高版本中的配合情况如何。
Windows 7 及更高版本支持的CSIDL
常量存在限制。在 Active Directory 或类似环境中的复杂、远程挂载、重定向和/或共享文件夹中,似乎也可能存在需要克服的问题。
另请参阅KNOWNFOLDERID,其中包括一个表,该表指示CSIDL
和SHGetFolderPath()
的一些限制。表中的一些示例CSIDL
可能有用的常量。
CSIDL_LOCAL_APPDATA - %USERPROFILE%AppDataLocal
CSIDL_MYDOCUMENTS - %USERPROFILE%Document
CSIDL_PERSONAL - %USERPROFILE%Documents
CSIDL_FONTS - %windir%Fonts
CSIDL_MYMUSIC - %USERPROFILE%Music
CSIDL_MYPICTURES - %USERPROFILE%Pictures
CSIDL_COMMON_APPDATA - %ALLUSERSPROFILE% (%ProgramData%, %SystemDrive%ProgramData)
CSIDL_COMMON_DOCUMENTS - %PUBLIC%Documents
顺便说一下,Shell 路径处理函数是一个很好的操作文件路径的方法库。
另请参阅将常见的可写应用程序文件放在哪里?
来自微软,altenate是"SHGetKnownFolderPath"https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderpatha
在我看来,这些函数适用于 c、c++ 和类似语言。从powershell,我刚刚阅读了注册表:PS> cd hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\PS>目录
在这里偷看"外壳文件夹"和"用户外壳文件夹"。
顺便说一句:这些是为了获取值。我会说这是相当安全的。对于设置值,最好不要直接使用注册表,因为它会毁了你的一天。使用这些"目录"的资源管理器 ->属性来移动它们,也会移动内容。不幸的是,我不知道在powershell中使用它的钩子。
- Paths.get( "abc/def.jpg" ) 在 C 和 C++ 中获取与操作系统无关的路径的等价物是什么?
- "-I" 和 "-L" 在添加到路径前面时是什么意思?
- "警告:并非所有控制路径都返回值"是什么意思?(C++)
- 在QT资源系统中,前缀比文件系统路径的优势是什么?
- 对于具有绝对路径的库的GCC行为是什么?
- 用CreateFile打开显示时,正确的路径是什么?
- 是什么让 clang 在包含路径的子目录中看起来?
- 确定两个文件路径引用同一文件对象的最佳方法是什么
- 可移植fstream文件路径的正确语法是什么
- 在C++中遍历二进制树中的每条路径的逻辑是什么
- curl_easy_setopt的默认路径是什么(卷曲、CURLOPT_CAINFO "cacert.pem");
- SHGetFolderPath 已弃用:检索 Windows 文件夹路径的替代方法是什么
- swig接口文件的正确sstream include路径是什么
- 在 c++ 中,知道路径是否引用文件夹或文件的最便宜的方法是什么?
- 组织一个C++游戏的最佳方式是什么?该游戏涉及用户在路径之间进行选择,以便在旅程中前进
- 确定给定路径是否包含路径分隔符的提升方式是什么
- 解析STD库作用域的路径是什么?
- 在源文件中指定include前缀与在编译器的搜索路径参数中指定include前缀的优缺点是什么
- 表示文件路径的guid字符串是什么?
- 将filesystem::path元素附加到另一个路径的最佳方法是什么?