我在查找并获取资源管理器显示的“最近的位置”下的所有项目时遇到问题。 我试过:
编辑:
HRESULT hr;
C_ComPtr<IShellItem> shellItem;
hr = SHCreateItemFromParsingName(TEXT("C:\Users\srvdsk\Links\RecentPlaces.lnk"), NULL, IID_PPV_ARGS(&shellItem));
if(S_OK != hr) return;
SFGAOF attrib;
shellItem->GetAttributes(SFGAO_FOLDER | SFGAO_LINK, &attrib);
if ( (attrib&SFGAO_LINK) ) {
C_ComPtr<IShellItem> linkTargetShellItem;
hr = shellItem->BindToHandler(NULL, BHID_LinkTargetItem, IID_PPV_ARGS(&linkTargetShellItem));
if (S_OK != hr) return;
linkTargetShellItem->GetAttributes(SFGAO_FOLDER | SFGAO_LINK, &attrib);
if ( (attrib&SFGAO_FOLDER) ) {
C_ComPtr<IShellFolder> shellFolder;
hr = linkTargetShellItem->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&shellFolder));
if (S_OK != hr) return;
C_ComPtr<IEnumIDList> enumIDList;
SHCONTF const flags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
hr = shellFolder->EnumObjects(NULL, flags, &enumIDList);
if (S_OK != hr) return;
LPITEMIDLIST childItemID = NULL;
while (S_OK == enumIDList->Next(1, &childItemID, NULL)) { //Next is returning S_FALSE in first iteration itself
STRRET strRetItemName;
hr = shellFolder->GetDisplayNameOf(childItemID, SHGDN_FORPARSING, &strRetItemName);
if (S_OK != hr) return;
}
}
}
答案 0 :(得分:0)
在这个地方你可以获得linkTargetShellItem:
shellItem->BindToHandler(NULL, BHID_LinkTargetItem, IID_PPV_ARGS(&linkTargetShellItem));
但是在这个地方你使用旧的shellItem:
shellItem->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&shellFolder));
你应该linkTargetShellItem而不是shellItem。
替代算法:
procedure IterateLinkTarget(const AFileName: UnicodeString);
var
ShellLink: IShellLinkW;
PersistFile: IPersistFile;
IDList: PItemIDList;
Desktop: IShellFolder;
Folder: IShellFolder;
Enum: IEnumIDList;
Child: PItemIDList;
Fetched: DWORD;
begin
OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IShellLinkW, ShellLink));
try
OleCheck(ShellLink.QueryInterface(IPersistFile, PersistFile));
try
OleCheck(PersistFile.Load(PWideChar(AFileName), STGM_READ));
OleCheck(ShellLink.GetIDList(IDList));
try
OleCheck(SHGetDesktopFolder(Desktop));
try
OleCheck(Desktop.BindToObject(IDList, nil, IShellFolder, Folder));
try
OleCheck(Folder.EnumObjects(0, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS, Enum));
while Enum.Next(1, Child, Fetched) = S_OK do
try
// Process child here
finally
CoTaskMemFree(Child);
end;
finally
Folder := nil;
end;
finally
Desktop := nil;
end;
finally
CoTaskMemFree(IDList);
end;
finally
PersistFile := nil;
end;
finally
ShellLink := nil;
end;
end;
答案 1 :(得分:0)
我花了很多年时间试图解决这个问题,并最终发现我的问题是CoInitializeEx(COINIT_MULTITHREADED)
。最近的items文件夹仅适用于COINIT_APARTMENTTHREADED
。请参阅此link。