use*_*556 2 c c++ windows winapi
我正在尝试以编程方式列出我的 win10 系统上所有已安装的应用程序。
基本上,我试图获取当您在资源管理器窗口中键入“shell:appsFolder”时可以看到的列表。
这是我使用的代码:
HRESULT hr;
IShellFolder *psParent= nullptr, *psApps= nullptr;
LPITEMIDLIST pidlSystem = NULL;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem); // get root pidl which is needed to get the parrent of our app folder
LPITEMIDLIST pidlApps= NULL;
if (!SUCCEEDED(hr= SHGetKnownFolderItem(FOLDERID_AppsFolder, KF_FLAG_DEFAULT, NULL, IID_IShellItem , (void**)&pidlApps)))
goto done; // get pidl for apps folder
if (!SUCCEEDED(hr=SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psParent, (LPCITEMIDLIST*)&pidlApps)))
goto done; // Get shell folder of parrent, which is needed to get shell folder of appsFolder
psApps= NULL;
if (!SUCCEEDED(hr= psParent->BindToObject(pidlApps, nullptr, IID_IShellFolder, (void **)&psApps)))
goto done; // finally get shell folder of appsFolder!
IEnumIDList *IDList;
if (!SUCCEEDED(hr= psApps->EnumObjects(nullptr, SHCONTF_NONFOLDERS, &IDList)))
goto done; // start the file scanning process
LPITEMIDLIST object= (LPITEMIDLIST)CoTaskMemAlloc(sizeof(*object)); // allocate room to receive data..
while (IDList->Next(1, &object, nullptr)!=S_FALSE) // and the list loop
{
STRRET strDispName;
if (!SUCCEEDED(hr= psApps->GetDisplayNameOf(object, SHGDN_NORMAL, &strDispName)))
continue; // get the name in some weired format
TCHAR szDisplayName[MAX_PATH];
if (!SUCCEEDED(hr= StrRetToBuf(&strDispName, pidlApps, szDisplayName, sizeof(szDisplayName))))
continue; // transform it to string...
ATLTRACE2(L"found %s\n", szDisplayName);
}
IDList->Release();
CoTaskMemFree(object);
Run Code Online (Sandbox Code Playgroud)
问题是我最终得到了超过 2000 个项目的列表,包括 .jpg 和其他 .dll 文件,但此列表与资源管理器窗口向我显示的内容不对应!例如,“word”不存在,既不作为链接,也不作为 winword.exe,而在资源管理器窗口中。
知道发生了什么事吗?
如果 shell:appsFolder 确实是您想要的,那么就使用它。像这样的东西:
\n\nCoInitialize(NULL);\nCComPtr<IShellItem> folder;\nif (SUCCEEDED(SHCreateItemFromParsingName(L"shell:appsFolder", nullptr, IID_PPV_ARGS(&folder))))\n{\n CComPtr<IEnumShellItems> enumItems;\n if (SUCCEEDED(folder->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&enumItems))))\n {\n IShellItem* items;\n while (enumItems->Next(1, &items, nullptr) == S_OK)\n {\n CComPtr<IShellItem> item = items;\n CComHeapPtr<wchar_t> name;\n if (SUCCEEDED(item->GetDisplayName(SIGDN_NORMALDISPLAY, &name)))\n {\n wprintf(L"%s\\n", name);\n }\n\n // dump all properties\n CComPtr<IPropertyStore> store;\n if (SUCCEEDED(item->BindToHandler(NULL, BHID_PropertyStore, IID_PPV_ARGS(&store))))\n {\n DWORD count = 0;\n store->GetCount(&count);\n for (DWORD i = 0; i < count; i++) {\n PROPERTYKEY pk;\n if (SUCCEEDED(store->GetAt(i, &pk)))\n {\n CComHeapPtr<wchar_t> pkName;\n PSGetNameFromPropertyKey(pk, &pkName); // needs propsys.lib\n\n PROPVARIANT pv;\n PropVariantInit(&pv);\n if (SUCCEEDED(store->GetValue(pk, &pv)))\n {\n CComHeapPtr<wchar_t> pvs;\n pvs.Allocate(512);\n PropVariantToString(pv, pvs, 512); // needs propvarutil.h and propsys.lib\n PropVariantClear(&pv);\n wprintf(L" %s=%s\\n", pkName, pvs);\n }\n else\n {\n wprintf(L" %s=???\\n", pkName);\n }\n }\n }\n }\n }\n }\n}\n\nCoUninitialize();\nRun Code Online (Sandbox Code Playgroud)\n\n注意1:我使用了Visual Studio的ATL智能类,这要容易得多。
\n\n注意2:我使用过IShellItem,这在某种程度上是对Shell 进行编程的新方法。您不再需要使用 IShellFolder、IEnumIDList、STRRET 等
\n\n注意3:我添加了一个代码来转储项目的所有属性。属性内容列表取决于应用程序的类型。这里有两个例子:
\n\nGoogle Chrome (not a UWP app)\n System.ItemNameDisplay=Google Chrome\n System.Keywords=chrome\n System.Tile.Background=4285031263\n System.Tile.Foreground=4294967295\n System.Tile.Square150x150LogoPath=79.0.3945.130\\VisualElements\\Logo.png\n System.Tile.Flags=1185\n System.Tile.Square70x70LogoPath=79.0.3945.130\\VisualElements\\SmallLogo.png\n System.ThumbnailCacheId=15284856079963922257\n System.Link.TargetParsingPath=C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\n System.AppUserModel.ID=Chrome\n System.AppUserModel.PreventPinning=0\n System.AppUserModel.BestShortcut=20; 0; 31; 80; 224; 79; 208; 32; 234; 58; 105; 16; 162; 216; 8; 0; 43; 48; 48; 157; 25; 0; 47; 67; 58; 92; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 98; 0; 49; 0; 0; 0; 0; 0; 0; 0; 0; 0; 16; 0; 80; 114; 111; 103; 114; 97; 109; 68; 97; 116; 97; 0; 72; 0; 9; 0; 4; 0; 239; 190; 0; 0; 0; 0; 0; 0; 0; 0; 46; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 80; 0; 114; 0; 111; 0; 103; 0; 114; 0; 97; 0; 109; 0; 68; 0; 97; 0; 116; 0; 97; 0; 0; 0; 26; 0; 92; 0; 49\n System.AppUserModel.HostEnvironment=0\n System.AppUserModel.InstalledBy=0\n System.AppUserModel.RunFlags=1\n ...\n\nPaint\xc2\xa03D (a UWP app).\n System.ItemNameDisplay=Paint\xc2\xa03D\n System.Tile.SmallLogoPath=Assets\\Logos\\Square44x44\\PaintAppList.png\n System.Tile.Background=4292311040\n System.Tile.Foreground=4294967295\n System.Tile.LongDisplayName=Paint\xc2\xa03D\n System.Tile.Square150x150LogoPath=Assets\\Logos\\Square150x150\\PaintMedTile.png\n System.Tile.Wide310x150LogoPath=Assets\\Logos\\Wide310x150\\PaintWideTile.png\n System.Tile.Flags=1185\n System.Tile.Square310x310LogoPath=Assets\\Logos\\Square310x310\\PaintLargeTile.png\n System.Tile.Square70x70LogoPath=Assets\\Logos\\Square71x71\\PaintSmallTile.png\n System.Launcher.AppState=0\n System.ThumbnailCacheId=10531553521183290931\n System.AppUserModel.ID=Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint\n System.AppUserModel.HostEnvironment=1\n System.AppUserModel.PackageInstallPath=C:\\Program Files\\WindowsApps\\Microsoft.MSPaint_6.1907.18017.0_x64__8wekyb3d8bbwe\n System.AppUserModel.PackageFamilyName=Microsoft.MSPaint_8wekyb3d8bbwe\n System.AppUserModel.PackageFullName=Microsoft.MSPaint_6.1907.18017.0_x64__8wekyb3d8bbwe\n System.AppUserModel.TileUniqueId={3911A337-8941-4141-9D5D-6C2575D40995}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1160 次 |
| 最近记录: |