I am trying to get installed location of all application using COM. I am able to get the display name of each application. But I am not able to get installed path of each application.
MY Code:
CComPtr<IShellItem> spPrinters; CoInitialize(nullptr); HRESULT hresult = ::SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\" L"::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&spPrinters)); CComPtr<IEnumShellItems> spEnum; spPrinters->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&spEnum)); for (CComPtr<IShellItem> spProgram; spEnum->Next(1, &spProgram, nullptr) == S_OK; spProgram.Release()) { CComHeapPtr<wchar_t> spszName; spProgram->GetDisplayName(SIGDN_NORMALDISPLAY, &spszName); CString cDisplayName = spszName; }
Any idea how to get installed path from IEnumShellItems.
Thanks in adv.
1 Answers
Answers 1
Here is a piece of code that will dump this out. The child's IPropertyStore does not return these, I don't know why, so we have to use the old IShellFolder2::GetDetailsEx method with a special column id (which is the same as a PROPERTYKEY).
CComPtr<IShellItem> cpl; CComPtr<IShellFolder2> folder; CComPtr<IEnumShellItems> enumerator; PROPERTYKEY pkLocation; SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&cpl)); // bind to IShellFolder cpl->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&folder)); // bind to IEnumShellItems cpl->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&enumerator)); // get this property key's value PSGetPropertyKeyFromName(L"System.Software.InstallLocation", &pkLocation); for (CComPtr<IShellItem> child; enumerator->Next(1, &child, nullptr) == S_OK; child.Release()) { // get child's display name CComHeapPtr<wchar_t> name; child->GetDisplayName(SIGDN_NORMALDISPLAY, &name); wprintf(L"%s\n", name); // get child's PIDL CComHeapPtr<ITEMIDLIST> pidl; SHGetIDListFromObject(child, &pidl); // the PIDL is absolute, we need the relative one (the last itemId in the list) // get it's install location CComVariant v; if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &pkLocation, &v))) { // it's a VT_BSTR wprintf(L" %s\n", v.bstrVal); } }
Note it's using an undocumented System.Software.InstallLocation
PROPERTYKEY. To find it I just dumped all columns with a code like this for each child:
int iCol = 0; do { SHCOLUMNID colId; if (FAILED(folder->MapColumnToSCID(iCol, &colId))) break; // last column CComHeapPtr<wchar_t> name; PSGetNameFromPropertyKey(colId, &name); CComVariant v; if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &colId, &v))) { if (v.vt == VT_BSTR) { wprintf(L" %s: %s\n", name, v.bstrVal); } else { wprintf(L" %s vt: %i\n", name, v.vt); } } iCol++; } while (true); }
PS: I've not added much error checking, but you should.
0 comments:
Post a Comment