枚举FOLDERID_NetworkFolder时如何仅显示网络打印机?
仅枚举网络打印机的代码修改方案
原代码枚举了FOLDERID_NetworkFolder下的所有网络设备,要筛选出网络打印机,核心是通过检查ShellItem的打印机属性来过滤。以下是修改后的完整代码:
hr = CoInitialize(NULL); if (FAILED(hr)) { printf("CoInitialize error, %x\n", hr); return; } hr = SHGetKnownFolderItem(FOLDERID_NetworkFolder, KF_FLAG_DEFAULT, NULL, IID_PPV_ARGS(&pShellItem)); if (FAILED(hr)) { printf("SHGetKnownFolderItem error, %x\n", hr); return; } hr = pShellItem->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&pShellEnum)); if (FAILED(hr)) { printf("BindToHandler error, %x\n", hr); return; } do { IShellItem* pItem = nullptr; LPWSTR szName = NULL; SFGAOF attributes = 0; hr = pShellEnum->Next(1, &pItem, nullptr); if (hr == S_OK && pItem) { // 获取ShellItem属性,检查是否为打印机 hr = pItem->GetAttributes(SFGAO_PRINTER, &attributes); if (SUCCEEDED(hr) && (attributes & SFGAO_PRINTER)) { hr = pItem->GetDisplayName(SIGDN_NORMALDISPLAY, &szName); if (SUCCEEDED(hr) && szName != NULL) { wcout << szName << std::endl; CoTaskMemFree(szName); // 释放字符串资源 } } pItem->Release(); // 释放IShellItem对象 } } while (hr == S_OK); // 释放全局Shell对象 if (pShellEnum) pShellEnum->Release(); if (pShellItem) pShellItem->Release(); CoUninitialize(); system("pause");
修改关键点说明
- 打印机属性过滤:调用
IShellItem::GetAttributes传入SFGAO_PRINTER标志,判断当前ShellItem是否为打印机设备,网络打印机同样会携带该属性 - 资源泄漏修复:补充
CoTaskMemFree释放szName、Release释放IShellItem/IShellEnumItems对象,避免内存泄漏 - 空指针安全:将
pItem初始化为nullptr,避免野指针风险
内容的提问来源于stack exchange,提问作者Arun Arun
相关产品推荐
相关产品推荐

