这是Delphi XE3探索:Winapi.Functiondiscovery系列到第二篇文章了。
思路分析
Discovery API 的重要功能之一是对设备枚举结果的筛选。为此需要用到CreateInstanceCollectionQuery 方法,然后使用AddPropertyConstraint 方法添加条件。
下面的代码尝试枚举了Intel的所有处理器。
{$APPTYPE CONSOLE} {$R *.res} uses System.Win.ComObj, Winapi.Windows, Winapi.Activex, Winapi.PropSys, Winapi.Functiondiscovery, System.SysUtils; procedure Enumerate; var LFunctionDiscovery : IFunctionDiscovery; LFunctionInstance : IFunctionInstance; ppIFunctionInstanceCollection: IFunctionInstanceCollection; ppIFunctionInstanceCollectionQuery: IFunctionInstanceCollectionQuery; ppIPropertyStore : IPropertyStore; pv : TPropVariant; pdwCount : DWORD; pszCategory: PWCHAR; hr : HResult; i : integer; begin //create an instance to the IFunctionDiscovery interface LFunctionDiscovery := CreateComObject(CLSID_FunctionDiscovery) as IFunctionDiscovery; try //set the provider to search pszCategory:=FCTN_CATEGORY_PNP; //get the devices collection hr := LFunctionDiscovery.CreateInstanceCollectionQuery(pszCategory, nil, false, nil, nil, ppIFunctionInstanceCollectionQuery); if Succeeded(hr) then begin PropVariantClear(pv); pv.vt:=VT_LPWSTR; pv.pwszVal:='Intel'; hr := ppIFunctionInstanceCollectionQuery.AddPropertyConstraint(PKEY_Device_Manufacturer, pv, QC_EQUALS); if not Succeeded(hr) then RaiseLastOSError; PropVariantClear(pv); pv.vt:=VT_LPWSTR; pv.pwszVal:='Processor'; hr := ppIFunctionInstanceCollectionQuery.AddPropertyConstraint(PKEY_Device_Class, pv, QC_EQUALS); if not Succeeded(hr) then RaiseLastOSError; hr := ppIFunctionInstanceCollectionQuery.Execute(ppIFunctionInstanceCollection); if Succeeded(hr) then begin //get the collection count ppIFunctionInstanceCollection.GetCount(pdwCount); if pdwCount=0 then Writeln(Format('No items was found for the %s category',[pszCategory])) else for i := 0 to pdwCount - 1 do begin //get the n Item of the collection if Succeeded(ppIFunctionInstanceCollection.Item(i, LFunctionInstance)) then begin //init the propertiess store LFunctionInstance.OpenPropertyStore(STGM_READ, ppIPropertyStore); //read the properties values if Succeeded(ppIPropertyStore.GetValue(PKEY_NAME, pv)) then Writeln(Format('Name %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_InstanceId, pv)) then Writeln(Format('Instance Id %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_Driver, pv)) then Writeln(Format('Device Driver %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_Model, pv)) then Writeln(Format('Model %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_Manufacturer, pv)) then Writeln(Format('Manufacturer %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_LocationInfo, pv)) then Writeln(Format('Location %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_Class, pv)) then Writeln(Format('Class %s',[pv.pwszVal])); if Succeeded(ppIPropertyStore.GetValue(PKEY_Device_ClassGuid, pv)) then Writeln(Format('Class Guid %s',[pv.puuid^.ToString])); Writeln; end else RaiseLastOSError; end; end; end else RaiseLastOSError; finally LFunctionDiscovery:=nil; end; end; begin try ReportMemoryLeaksOnShutdown:=True; if (Win32MajorVersion >= 6) then // available on Vista (or later) begin if Succeeded(CoInitializeEx(nil, COINIT_MULTITHREADED)) then try Enumerate; finally CoUninitialize; end; end else Writeln('Windows version not compatible'); except on E:Exception do Writeln(E.Classname, ':', E.Message); end; Writeln('Press Enter to exit'); Readln; end.
转载需保留链接来源:软件玩家 » Delphi XE3探索:Winapi.Functiondiscovery (二)