从Windows Vista开始,已弃用SHGetFolderPath()
函数: http : //msdn.microsoft.com/zh-cn/library/bb762181%28v=VS.85%29.aspx
在Windows中检索应用程序文件夹path的另一种方法是什么?
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
。
就我个人而言,我不会让这种贬低过度担心。 微软以维护向后兼容性而闻名。 不要期望SHGetFolderPath
很快消失。 你会发现SHGetFolderPath
存在于Windows 8中,我预计它现在仍然存在于10年后的任何Windows中。 我的建议是坚持加载时间链接,只有切换到SHGetKnownFolderPath
当你放弃支持XP。
你的另一个问题,就是如何调用SHGetFolderPath
。 您需要尊重在您的问题中链接到的MSDN文档主题底部所列出的要求。 具体来说,包括Shlobj.h
并将Shlobj.h
传递给链接器。
它被链接在顶部, SHGetKnownFolderPath 。
CSIDL_COMMON_APPDATA被新的API中的FOLDERID_ProgramData所取代。
我已经在Windows 10 PC上使用SHGetFolderPath()
与Visual Studio 2015 Enterprise进行了测试,并且编译并正常工作以找到当前用户的主文件夹。 在SHGetFolderPath()
SHGetFolderPath函数的Windows开发人员中心页面中有以下注释:
注意从Windows Vista开始,此函数仅仅是
SHGetKnownFolderPath
的包装器。 将CSIDL
值转换为与其关联的KNOWNFOLDERID
,然后SHGetKnownFolderPath
。 新的应用程序应该使用已知的文件夹系统,而不是旧版本的CSIDL
系统,后者仅支持向后兼容。
正如David Heffman在答复中指出的那样,微软在多年的时间里保持向后兼容性的历史,尤其是当他们可以采用旧的功能,并将其重定向到具有适当参数的新功能时。 CSIDL
值似乎有一个相应的KNOWNFOLDERID
值。 请参阅此CSIDL
常量表,其中包含简短的注释和相应的KNOWNFOLDERID
值。
下面是一个使用该功能的例子。 此用法检索当前用户的用户文件夹(例如Windows 7下的“C:\ Users \ myuser \ Documents”),然后使用PathAppend()
函数将文件夹名称添加到路径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
常量可以用来修改函数的结果,如CSIDL_FLAG_CREATE
通过使用按位或运算符。 我不确定这些操作员能够在Windows 7及更高版本中工作得如何。
Windows 7及更高版本支持的CSIDL
常量有限制。 在Active Directory或类似的环境中,复杂,远程安装,重定向和/或共享文件夹也可能需要克服。
另请参见KNOWNFOLDERID ,其中包含一个表,指出CSIDL
和SHGetFolderPath()
一些限制。 CSIDL
常量表中的一些示例可能有用。
CSIDL_LOCAL_APPDATA - %USERPROFILE%\AppData\Local 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路径处理函数是一个很好的操作文件路径的方法库。
另请参见在何处放置常用的可写应用程序文件?