[编辑-这个问题的标题具有误导性,所以我对其进行了编辑,无论如何,这个问题都是假的。 TL;DR - 零字节文件是我错误创建的]。请随意取消这个问题或将其留在这里作为我愚蠢的纪念碑。
我想获取快捷方式(.lnk)文件的目标。如果目标不存在,我想要一个空字符串(或返回 S_FALSE,无论哪种方式)。
此代码有效,除非目标不存在时,它会在目标应在的位置创建一个空文件。
有谁知道如何做到这一点?如果我删除对
persistFile->Load()
的调用,则无论目标是否存在,shellLink->GetPath()
函数都会返回一个空字符串。
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;
}
// don't look for it if it's not there
hr = shellLink->Resolve(null, SLR_NO_UI | SLR_NOUPDATE | SLR_NOSEARCH | SLR_NOTRACK | 0x00010000);
if(FAILED(hr)) {
return S_FALSE;
}
// persistFile->Load() creates a zero byte file at the target location if it doesn't exist
hr = persistFile->Load(shortcut_filename.c_str(), STGM_READ);
if(FAILED(hr)) {
return S_FALSE;
}
wchar_t target_path[MAX_PATH * 4];
hr = shellLink->GetPath(target_path, _countof(target_path), 0, SLGP_RAWPATH);
if(FAILED(hr)) {
return S_FALSE;
}
path = std::wstring(target_path);
return S_OK;
}
如果有人遇到这个问题寻找已编辑问题的答案,这就是我的结局:
HRESULT path_from_shortcut(std::wstring const &shortcut_filename, std::wstring &path)
{
ComPtr<IShellLinkW> shellLink;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shell_link));
if(FAILED(hr)) {
return hr;
}
ComPtr<IPersistFile> persistFile;
hr = shellLink.As(&persistFile);
if(FAILED(hr)) {
return hr;
}
hr = persistFile->Load(shortcut_filename.c_str(), STGM_READ);
if(FAILED(hr)) {
return hr;
}
LPITEMIDLIST itemIdList{NULL};
hr = shellLink->GetIDList(&itemIdList);
if(FAILED(hr)) {
return hr;
}
wchar target_path[MAX_PATH];
hr = E_FAIL;
if(SHGetPathFromIDList(itemIdList, target_path)) {
path = std::wstring(target_path);
hr = S_OK;
}
if(itemIdList != NULL) {
CoTaskMemFree(itemIdList);
}
return hr;
}