Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WMI Methods and the Registry

System Information

WMI Methods and the Registry

by  Glenn9999  Posted    (Edited  )
Previous FAQ: faq102-7315

As recalled in the previous FAQ, the discussion was on how to obtain system information from WMI. Several wrapper routines were provided in that FAQ and they will be used on these examples as well.

As one may notice in the MSDN WMI documentation, some of the WMI objects have methods attached to them. Here, how to call these methods will be described. Furthermore, since method calls are required to access the registry in WMI, an example of registry access will be provided as well.

Example #1: Starting a Service

This example presupposes that a combobox was filled prior to it with values that were obtained from the statement select caption from Win32_Service. This is not shown since it covers material involved in the first FAQ.

As well, the status of this service is not checked, though it can be done easily through using the OnSelect event of the ComboBox and the buttons enabled or disabled as dictated.

The method to start a service is simply Win32_Service.StartService. No parameters. This is because all methods, when dictated in directions, operate on the current selected record. This means we have to go out and get that record before we call the method. This is reasonably standard for most methods in WMI.

Example Code is below:
Code:
procedure TForm1.Button2Click(Sender: TObject);
// start service
var
  WbemLocator: ISWbemLocator;
  WbemServices: ISWbemServices;
  ObjectSet: ISWbemObjectSet;
  InParam: ISWBemObject;
  tempobj: OleVariant;
  InProcess: ISWBemObject;
  RowENum: IENumVariant;
  outstmt: string;
begin
  WBemLocator := WMIStart;
  WBemServices := WMIConnect(WBemLocator, '', '', '');

  outstmt := 'Select caption from Win32_Service where caption = ''' +
  ComboBox1.Items[ComboBox1.Itemindex] + '''';
  ObjectSet := WMIExecQuery(WbemServices, outstmt);
  WMIRowFindFirst(ObjectSet, RowENum, tempobj);

  InProcess := IUnknown(tempobj) as ISWbemobject;
  InParam := InProcess.ExecMethod_('StartService', nil, 0, nil);

end;

Example #2: Obtaining a key from the registry.

Those of you who are familiar with TRegistry will know there are a great many methods there to access and use the registry. The registry object in WMI is no different. This example will focus on obtaining a string from a specific path.

The first thing to note from this example is that the connection process to WMI is a bit different. The registry object, StdRegProv, is located in the namespace "default", which involves a slightly different connection process.

This method call is a lot more complex, showing the process of providing parms and retrieving them from the method when done.

Code:
unit regunit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  activex, wmiserv, WbemScripting_TLBa, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  WBEMLocator: SWBEMLocator;
  WBEMServices: ISWBEMServices;
  regobject: ISWBemObject;
  InParam, OutParam: ISWBemObject;
  InProp: ISWBemProperty;
  outv: Olevariant;
begin
  WBEMLocator := WMIStart;
  WBemServices := WMIRegConnect(WBEMLocator, '', '', '');

  WMIGetMethodInfo(WBEMServices, regobjstring, 'GetExpandedStringValue',
                   regobject, InParam);

  WMISetValue(InParam, 'hDefKey', HKEY_CURRENT_USER);
  WMISetValue(InParam, 'sSubKeyName', 'Control Panel\Desktop');
  WMISetValue(InParam, 'sValueName', 'Wallpaper');

  OutParam := regobject.ExecMethod_('GetExpandedStringValue', InParam, 0, nil);

  // output value is SValue
  InProp := OutParam.Properties_.Item('sValue', 0);
  outv := InProp.Get_Value;

  ShowMessage(outv); // the value of the registry key
end;

end.

Additional code below, which can be inserted into WMISERV.PAS in the last FAQ in the appropriate spots

Code:
  const
    regobjstring = 'StdRegProv';

function WMIRegConnect(WBemLocator: ISWBemLocator; Server, account, password: string): ISWBemServices;
// connects to the default area 
  begin
    Result := nil;
    try
      Result := WBEMLocator.ConnectServer(Server, 'root\default', '', Account,
               Password, '', 0, nil);
    except
      on EOleException do
        raise EOleException.Create('incorrect credentials.  WMI connection failed.', 1, '', '', 0);
    end;
    CoSetProxyBlanket(Result, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
             nil,
             wbemAuthenticationLevelCall, wbemImpersonationLevelImpersonate,
             nil, EOAC_NONE);
  end;

procedure WMIGetMethodInfo(srv: ISWbemServices; objname, method: string;  var regobject, inparms: ISWBemObject);
// gets method info and parms, this is useful if an object method is *NOT* tied to a specific record.
  begin
    regobject := srv.Get(objname, 0, nil);
    InParms := regobject.Methods_.Item(method, 0).InParameters;
  end;

procedure WMISetValue(InParam: ISWBemObject; keyvalue: string; invalue: OleVariant);
// sets a parm value.  Calls my modified set_value.
// remove the @ if you wish to make the default call.
  begin
    InParam.Properties_.Item(keyvalue, 0).Set_Value(@InValue);
  end;
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top