Mega Code Archive

 
Categories / Delphi / System
 

WMI Methods and the Registry

Title: WMI Methods and the Registry Previous FAQ: FAQ102-7315: Get System information from WMI 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;