如何获取.lnk快捷方式目标且避免创建空文件?
获取.lnk快捷方式目标路径的问题解决
需求:获取.lnk快捷方式的目标路径,当目标不存在时返回空字符串或S_FALSE。
当前代码存在两个问题:
- 目标不存在时,会在目标路径下创建一个空文件
- 移除
persistFile->Load()后,shellLink->GetPath()始终返回空字符串
问题根源
你把shellLink->Resolve()和persistFile->Load()的调用顺序搞反了!应该先加载快捷方式文件,再去解析目标路径。现在的顺序是先对一个未加载任何快捷方式数据的IShellLink对象调用Resolve,这会触发错误的文件创建逻辑。
修正后的代码
HRESULT path_from_shortcut(std::wstring const &shortcut_filename, std::wstring &path) { HRESULT hr; ComPtr<IShellLinkW> shellLink; hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, reinterpret_cast<LPVOID *>(shellLink.GetAddressOf())); if(FAILED(hr)) { return hr; } ComPtr<IPersistFile> persistFile; hr = shellLink->QueryInterface(IID_IPersistFile, reinterpret_cast<LPVOID *>(persistFile.GetAddressOf())); if(FAILED(hr)) { return hr; } // 先加载快捷方式文件,这一步必须在Resolve之前 hr = persistFile->Load(shortcut_filename.c_str(), STGM_READ | STGM_SHARE_DENY_WRITE); if(FAILED(hr)) { return S_FALSE; } // 解析目标路径,设置标志避免自动创建文件、搜索或更新快捷方式 hr = shellLink->Resolve(nullptr, SLR_NO_UI | SLR_NOUPDATE | SLR_NOSEARCH | SLR_NOTRACK); if(FAILED(hr)) { // 如果目标不存在,Resolve会返回类似ERROR_FILE_NOT_FOUND的错误,直接返回S_FALSE return S_FALSE; } wchar_t target_path[MAX_PATH * 4]; hr = shellLink->GetPath(target_path, _countof(target_path), nullptr, SLGP_RAWPATH); if(FAILED(hr)) { return S_FALSE; } path = std::wstring(target_path); return S_OK; }
关键修改说明
- 调整调用顺序:先调用
persistFile->Load()加载快捷方式的实际数据,再调用shellLink->Resolve()解析目标路径,这是符合COM对象使用逻辑的正确顺序。 - 优化Load的存储模式:添加
STGM_SHARE_DENY_WRITE,避免加载快捷方式时锁定文件导致其他进程无法访问。 - 修正Resolve的标志:移除了自定义的
0x00010000标志(未公开的私有标志,可能引发意外行为),只保留官方文档明确支持的标志。 - 错误处理逻辑:当Resolve失败(比如目标文件不存在),直接返回
S_FALSE,不会触发空文件创建。
内容的提问来源于stack exchange,提问作者Charlie Skilbeck
相关产品推荐
相关产品推荐

