目录1.背景2.Window目录介绍3.解决方案1.背景在Windows10、Windows11和Window7的大部分电脑用SHGetKnownFolderPath获取“我的文档”都没有问题然而今天在公司的一台Windows7 SP1电脑上用SHGetKnownFolderPath获取“我的文档”失败下面将展开分析原因和解决方案。大致源码如下#include windows.h #include shlobj.h // 包含SHGetKnownFolderPath和FOLDERID定义 #include stdio.h // 用于控制台输出 #include locale.h // 解决中文路径显示乱码问题 #pragma comment(lib, shell32.lib) // 链接shell32库必须 int main() { // 解决Win7控制台中文路径显示乱码可选但推荐 setlocale(LC_ALL, chs); PWSTR pszDocPath NULL; // 接收API返回的文档目录路径宽字符 HRESULT hr S_OK; // 核心调用获取「我的文档」目录 // 参数说明 // 1. FOLDERID_Documents固定标识「我的文档」 // 2. 0无特殊标志可用KF_FLAG_CREATE确保目录存在 // 3. NULL当前用户令牌获取当前登录用户的文档目录 // 4. pszDocPath输出路径由系统分配内存需手动释放 hr SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, pszDocPath); // 结果判断与处理 if (SUCCEEDED(hr)) { // 输出宽字符路径%ls适配wchar_t wprintf(L我的文档目录%ls\n, pszDocPath); // 【关键】释放系统分配的内存避免内存泄漏 CoTaskMemFree(pszDocPath); pszDocPath NULL; } else { // 错误码提示方便排查问题 printf(获取失败错误码0x%08X\n, hr); // 常见错误码说明 // 0x80070002 (ERROR_FILE_NOT_FOUND)目录不存在加KF_FLAG_CREATE可自动创建 // 0x80070005 (E_ACCESSDENIED)权限不足 } system(pause); // 暂停控制台方便查看结果 return 0; }2.Window目录介绍Win7 SP1 中当前登录用户的根目录最通用的获取方式是系统环境变量%USERPROFILE%默认物理路径为C:\Users\你的用户名中文系统资源管理器中会显示为「C:\ 用户 \ 你的用户名」以下是不同场景的完整获取方法。可直接通过%USERPROFILE%变量引用示例echo off :: 切换到用户主目录支持跨盘符 cd /d %USERPROFILE% :: 输出路径到txt文件 echo 当前用户目录%USERPROFILE% 用户目录路径.txt pause常用用户子目录对应表:目录用途环境变量 / Shell 命令默认路径用户主目录%USERPROFILE% / shell:ProfileC:\Users\ 用户名桌面%USERPROFILE%\Desktop / shell:DesktopC:\Users\ 用户名 \Desktop我的文档%USERPROFILE%\Documents / shell:PersonalC:\Users\ 用户名 \Documents下载%USERPROFILE%\Downloads / shell:DownloadsC:\Users\ 用户名 \Downloads图片%USERPROFILE%\Pictures / shell:MyPicturesC:\Users\ 用户名 \Pictures漫游应用数据%APPDATA% / shell:AppDataC:\Users\ 用户名 \AppData\Roaming本地应用数据%LOCALAPPDATA% / shell:LocalAppDataC:\Users\ 用户名 \AppData\Local公共用户目录%PUBLIC% / shell:PublicC:\Users\Public3.解决方案先用SHGetFolderPath的CSIDL_PROFILE获取当前用户目录再加上固定文档目录就可以了如下代码#include windows.h #include shlobj.h #include stdio.h #pragma comment(lib, shell32.lib) int main() { WCHAR szUserPath[MAX_PATH] {0}; // CSIDL_PROFILE 对应当前用户主目录 HRESULT hr SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, szUserPath); if (SUCCEEDED(hr)) { wprintf(L当前用户目录%s\n, szUserPath); std::wstring path szUserPathL\\Documents; wprintf(L当前用户文档目录%s\n, path.data()); } return 0; }
Win7系统SHGetKnownFolderPath获取“我的文档”目录失败的解决方案
目录1.背景2.Window目录介绍3.解决方案1.背景在Windows10、Windows11和Window7的大部分电脑用SHGetKnownFolderPath获取“我的文档”都没有问题然而今天在公司的一台Windows7 SP1电脑上用SHGetKnownFolderPath获取“我的文档”失败下面将展开分析原因和解决方案。大致源码如下#include windows.h #include shlobj.h // 包含SHGetKnownFolderPath和FOLDERID定义 #include stdio.h // 用于控制台输出 #include locale.h // 解决中文路径显示乱码问题 #pragma comment(lib, shell32.lib) // 链接shell32库必须 int main() { // 解决Win7控制台中文路径显示乱码可选但推荐 setlocale(LC_ALL, chs); PWSTR pszDocPath NULL; // 接收API返回的文档目录路径宽字符 HRESULT hr S_OK; // 核心调用获取「我的文档」目录 // 参数说明 // 1. FOLDERID_Documents固定标识「我的文档」 // 2. 0无特殊标志可用KF_FLAG_CREATE确保目录存在 // 3. NULL当前用户令牌获取当前登录用户的文档目录 // 4. pszDocPath输出路径由系统分配内存需手动释放 hr SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, pszDocPath); // 结果判断与处理 if (SUCCEEDED(hr)) { // 输出宽字符路径%ls适配wchar_t wprintf(L我的文档目录%ls\n, pszDocPath); // 【关键】释放系统分配的内存避免内存泄漏 CoTaskMemFree(pszDocPath); pszDocPath NULL; } else { // 错误码提示方便排查问题 printf(获取失败错误码0x%08X\n, hr); // 常见错误码说明 // 0x80070002 (ERROR_FILE_NOT_FOUND)目录不存在加KF_FLAG_CREATE可自动创建 // 0x80070005 (E_ACCESSDENIED)权限不足 } system(pause); // 暂停控制台方便查看结果 return 0; }2.Window目录介绍Win7 SP1 中当前登录用户的根目录最通用的获取方式是系统环境变量%USERPROFILE%默认物理路径为C:\Users\你的用户名中文系统资源管理器中会显示为「C:\ 用户 \ 你的用户名」以下是不同场景的完整获取方法。可直接通过%USERPROFILE%变量引用示例echo off :: 切换到用户主目录支持跨盘符 cd /d %USERPROFILE% :: 输出路径到txt文件 echo 当前用户目录%USERPROFILE% 用户目录路径.txt pause常用用户子目录对应表:目录用途环境变量 / Shell 命令默认路径用户主目录%USERPROFILE% / shell:ProfileC:\Users\ 用户名桌面%USERPROFILE%\Desktop / shell:DesktopC:\Users\ 用户名 \Desktop我的文档%USERPROFILE%\Documents / shell:PersonalC:\Users\ 用户名 \Documents下载%USERPROFILE%\Downloads / shell:DownloadsC:\Users\ 用户名 \Downloads图片%USERPROFILE%\Pictures / shell:MyPicturesC:\Users\ 用户名 \Pictures漫游应用数据%APPDATA% / shell:AppDataC:\Users\ 用户名 \AppData\Roaming本地应用数据%LOCALAPPDATA% / shell:LocalAppDataC:\Users\ 用户名 \AppData\Local公共用户目录%PUBLIC% / shell:PublicC:\Users\Public3.解决方案先用SHGetFolderPath的CSIDL_PROFILE获取当前用户目录再加上固定文档目录就可以了如下代码#include windows.h #include shlobj.h #include stdio.h #pragma comment(lib, shell32.lib) int main() { WCHAR szUserPath[MAX_PATH] {0}; // CSIDL_PROFILE 对应当前用户主目录 HRESULT hr SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, szUserPath); if (SUCCEEDED(hr)) { wprintf(L当前用户目录%s\n, szUserPath); std::wstring path szUserPathL\\Documents; wprintf(L当前用户文档目录%s\n, path.data()); } return 0; }