Somebody asked me to help him get a working delphi code for SWbemRefresher. I obviously tried the first natural approach of using the WbemScripting_TLB unit but that didn’t work.
So, since I couldn’t get the early binding to work (using the interfaces and such) and since the VBS code from MSDN works (I previously tested it), I went with late binding just as VBS, which obviously worked. here’s the code:
http://msdn.microsoft.com/en-us/library/aa393838%28VS.85%29.aspx
function GetObject(Value: String): IUnknown;
// from russel: http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_20875677.html
var pUnk: IUnknown;
pmk: IMoniker;
pbc: IBindCtx;
cbEaten: LongInt;
clsid: TGUID;
begin
// Check value to determine if this is a programmatic id or a moniker
if (CLSIDFromProgID(PWideChar(WideString(Value)), clsid) = S_OK) then
begin
// Attempt to get the active object, clear the result on failure
if not(GetActiveObject(clsid, nil, result) = S_OK) then result:=nil;
end
else
begin
// Moniker name
if (CreateBindCtx(0, pbc) = S_OK) then
begin
if (MkParseDisplayName(pbc, StringToOleStr(Value), cbEaten, pmk) = S_OK) then
begin
// Attempt to bind the moniker, clear the result on failure
if not(BindMoniker(pmk, 0, IUnknown, result) = S_OK) then result:=nil;
// Release the moniker
pmk:=nil;
end;
// Release the bind context
pbc:=nil;
end;
end;
end;
procedure getprocesslate;
var objServicesCimv2,
objServicesDefault,
objRefreshableItem1,
objRefreshableItem2,
RefreshableItem,
objRefresher:OleVariant;
i:integer;
begin
// Get namespace connections
objServicesCimv2 := GetObject('winmgmts:root\cimv2');
objServicesDefault := GetObject('winmgmts:root\default');
// Create a refresher object
objRefresher := CreateOleObject('WbemScripting.SWbemRefresher');
// Add a single object (SWbemObjectEx) to the refresher. The "@"
// is used because _CIMOMIdentification is a singleton class- only
// one instance exists. Note that the
// SWbemRefreshableItem.Object property must
// be specified or the SWbemRefresher.Refresh call will fail.
objRefreshableItem1 := objRefresher.Add(objServicesDefault, '__CIMOMIdentification=@').Object;
// Add an enumerator (SWbemObjectSet object)
// to the refresher. Note that the
// SWbemRefreshableItem.ObjectSet property
// must be specified or the SWbemRefresher.Refresh call will fail.
objRefreshableItem2 := objRefresher.AddEnum(objServicesCimv2, 'Win32_Process').ObjectSet;
// Display number of items in refresher and update the data.
ShowMessage('Number of items in refresher = ' +inttostr( objRefresher.Count));
objRefresher.Refresh;
// Iterate through the refresher. SWbemRefreshable
// Item.IsSet checks for whether the item is an enumerator.
for i := 1 to objRefresher.Count do
begin
RefreshableItem:=objRefresher.Item(i);
if RefreshableItem.IsSet then
ShowMessage('Item with index ' + IntToStr(RefreshableItem.Index) +
' is an enumerator containing ' + IntToStr(RefreshableItem.ObjectSet.Count) + ' processes')
else
ShowMessage('Item with index ' + IntToStr(RefreshableItem.Index) +
' is a single object containing WMI version ' + objRefreshableItem1.VersionCurrentlyRunning);
end;
end;