How can I improve the WMI performance using delphi?

前端 未结 2 947
别那么骄傲
别那么骄傲 2020-12-30 05:54

I wrote a simple function to retrieve system information using the WMI, passing as parameter the class and the property name. when I execute the function like this

2条回答
  •  礼貌的吻别
    2020-12-30 06:27

    These are some tips to improve the WMI performance

    1.) Reutilize the call to CreateOleObject

    2.) Reuse the WMI Connection

    One of more expensive tasks is make a connection to the WMI services, so reutilize that conneciton instead of create one conneciton each time which call the function.

    3.) Only retrieve the columns which you want to use

    Every property which retrieve the WMI has different sources like the Windows registry, the WinAPi and so on, restricting the columns will improve the performance. read this article for more info How obtain the source of the WMI Data

    4.) Use the WBEM_FLAG_FORWARD_ONLY flag when you execute the WQL sentence.

    Following the above tips I rewrote your sample app

    {$APPTYPE CONSOLE}
    
    uses
      Diagnostics,
      SysUtils,
      ActiveX,
      ComObj,
      Variants;
    
    var
      FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;
    
    function  GetWMIInfo(const WMIClass, WMIProperty:string): string;
    const
      wbemFlagForwardOnly = $00000020;
    var
      FWbemObjectSet: OLEVariant;
      FWbemObject   : OLEVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
    begin;
      Result:='';
      FWbemObjectSet:= FWMIService.ExecQuery(Format('Select %s from %s',[WMIProperty, WMIClass]),'WQL',wbemFlagForwardOnly);
      oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      if oEnum.Next(1, FWbemObject, iValue) = 0 then
        Result:=FWbemObject.Properties_.Item(WMIProperty).Value;
    end;
    
    var
     SW : TStopwatch;
    
    begin
     try
        CoInitialize(nil);
        try
          SW.Reset;
          SW.Start;
          FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
          FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
          Writeln('Procesor Id '+GetWMIInfo('Win32_Processor','Name'));
          Writeln('Mother Board Serial '+GetWMIInfo('Win32_BaseBoard','SerialNumber'));
          Writeln('BIOS Version '+GetWMIInfo('Win32_BIOS','Version'));
          SW.Stop;
          Writeln('Elapsed ms '+FormatFloat('#,0.000',SW.Elapsed.TotalMilliseconds));
        finally
          CoUninitialize;
        end;
     except
        on E:EOleException do
            Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
        on E:Exception do
            Writeln(E.Classname, ':', E.Message);
     end;
     Readln;
    end.
    

    And the execution goes from 1245 to 180 ms (on my laptop).

提交回复
热议问题