1
1
{ ***************************************************************************
2
2
3
- Copyright (c) 2016-2019 Kike Pérez
3
+ Copyright (c) 2016-2020 Kike Pérez
4
4
5
5
Unit : Quick.WMI
6
6
Description : Common functions
7
7
Author : Kike Pérez
8
- Version : 1.0
8
+ Version : 1.1
9
9
Created : 04/04/2019
10
- Modified : 08 /04/2019
10
+ Modified : 22 /04/2020
11
11
12
12
This file is part of QuickLib: https://github.com/exilon/QuickLib
13
13
@@ -40,47 +40,99 @@ interface
40
40
41
41
uses
42
42
SysUtils,
43
- WbemScripting_TLB,
44
43
ActiveX,
45
44
ComObj,
45
+ Quick.Commons,
46
+ Quick.Collections,
46
47
Quick.Arrays,
47
48
Quick.Value ,
48
49
Variants;
49
50
50
51
type
51
52
52
- TFlexArray = TArray<TFlexValue>;
53
+ IWMIInstance = interface
54
+ [' {4C81A6A6-4A65-46FB-B05B-5898DF51F9B7}' ]
55
+ function GetProperty (const aPropertyName : string) : TFlexValue;
56
+ function GetProperties (const aProperties : TArray<string>) : IList<TFlexPair>;
57
+ function GetName : string;
58
+ end ;
53
59
54
- TWMIObject = record
60
+ TWMIInstance = class (TInterfacedObject,IWMIInstance)
55
61
private
56
62
fInstance : string;
57
- fProperty : string;
63
+ fWMIItem : OleVariant;
64
+ public
65
+ constructor Create(const aInstanceName : string; aWMIItem: OleVariant);
66
+ destructor Destroy; override;
67
+ function GetProperty (const aPropertyName : string) : TFlexValue;
68
+ function GetProperties (const aProperties : TArray<string>) : IList<TFlexPair>;
69
+ function GetName : string;
58
70
end ;
59
71
60
- TWMICollector = class
61
- private
62
- class function GetObject ( const aObjectName: string) : IDispatch;
63
- public
64
- class function GetProperty (const aWMIHost, aRoot, aWMIClass, aWMIProperty : string) : TFlexValue ;
65
- class function GetPropertyInstances (const aWMIHost, aRoot, aWMIClass,aWMIProperty : string; const aInstances : string = ' * ' ) : TFlexPairArray ;
72
+ TWMIInstances = TArray<IWMIInstance>;
73
+
74
+ IWMIClass = interface
75
+ [ ' {FAFE26ED-28BC-4591-AE5A-9E4543074B5C} ' ]
76
+ function GetInstance (const aInstance : string) : IWMIInstance ;
77
+ function GetInstances (const aInstances : TArray< string> ) : TWMIInstances ;
66
78
end ;
67
79
68
- TWMIInstance = class
80
+ TWMIClass = class (TInterfacedObject,IWMIClass)
69
81
private
70
- fInstance : string;
82
+ fClassName : string;
83
+ fWMIService : OleVariant;
84
+ fWMIClassItems : IEnumvariant;
85
+ function GetInstanceName (aWMIClass : OleVariant) : string;
71
86
public
72
- property Instance :
87
+ constructor Create(aWMIService : OleVariant; const aClassName : string; aWMIClassItems : IEnumvariant);
88
+ destructor Destroy; override;
89
+ function GetInstance (const aInstance : string) : IWMIInstance;
90
+ function GetInstances (const aInstances : TArray<string>) : TWMIInstances;
73
91
end ;
74
92
75
- TWMIObject2 = class
93
+ IWMICollector = interface
94
+ [' {3FFFF0DC-F533-4FE1-A511-73E76EC6BCC8}' ]
95
+ function From (const aRoot, aWMIClass : string) : IWMIClass; overload;
96
+ function From (const aHost, aRoot, aWMIClass : string) : IWMIClass; overload;
97
+ end ;
98
+
99
+ TWMICollector = class (TInterfacedObject,IWMICollector)
100
+ private
101
+ fNamespace : string;
102
+ fWMIService : OleVariant;
76
103
public
77
- function FromInstance (const aInstanceName : string) : TWMIInstance;
104
+ constructor Create;
105
+ destructor Destroy; override;
106
+ class function GetObject (const aObjectName: string) : IDispatch;
107
+ function From (const aRoot, aWMIClass : string) : IWMIClass; overload;
108
+ function From (const aHost, aRoot, aWMIClass : string) : IWMIClass; overload;
78
109
end ;
79
110
80
111
EWMICollector = class (Exception);
81
112
82
113
implementation
83
114
115
+ const
116
+ wbemFlagUseAmendedQualifiers = $00020000 ;
117
+ wbemFlagReturnImmediately = $00000010 ;
118
+ wbemFlagReturnWhenComplete = $00000000 ;
119
+ wbemFlagForwardOnly = $00000020 ;
120
+
121
+ { TWMICollector }
122
+
123
+ constructor TWMICollector.Create;
124
+ begin
125
+ fNamespace := ' ' ;
126
+ CoInitialize(nil );
127
+ end ;
128
+
129
+ destructor TWMICollector.Destroy;
130
+ begin
131
+ fWMIService := Unassigned;
132
+ CoUninitialize;
133
+ inherited ;
134
+ end ;
135
+
84
136
class function TWMICollector.GetObject (const aObjectName: string) : IDispatch;
85
137
var
86
138
chEaten : Integer;
@@ -92,59 +144,166 @@ class function TWMICollector.GetObject(const aObjectName: string) : IDispatch;
92
144
OleCheck(Moniker.BindToObject(bindCtx, nil , IDispatch, Result));
93
145
end ;
94
146
95
- class function TWMICollector.GetProperty (const aWMIHost, aRoot, aWMIClass, aWMIProperty: string) : TFlexValue;
147
+ function TWMICollector.From (const aRoot, aWMIClass : string) : IWMIClass;
148
+ begin
149
+ Result := From(' .' ,aRoot,aWMIClass);
150
+ end ;
151
+
152
+ function TWMICollector.From (const aHost, aRoot, aWMIClass : string) : IWMIClass;
96
153
var
97
- objWMIService : OLEVariant;
98
154
colItems : OLEVariant;
99
- colItem : OLEVariant;
100
155
oEnum : IEnumvariant;
101
- iValue : LongWord;
102
156
begin
103
- CoInitialize(nil );
104
157
try
158
+ // only connect if namespace is different from previous connection
159
+ if fNamespace <> aHost + ' \' + aRoot then
160
+ begin
161
+ fWMIService := GetObject(Format(' winmgmts:\\%s\%s' ,[aHost,aRoot]));
162
+ fNamespace := aHost + ' \' + aRoot;
163
+ end ;
164
+ colItems := fWMIService.ExecQuery(Format(' SELECT * FROM %s' ,[aWMIClass]),' WQL' ,wbemFlagForwardOnly and wbemFlagReturnImmediately);
165
+ oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
166
+ Result := TWMIClass.Create(fWMIService,aWMIClass,oEnum);
167
+ except
168
+ on E : Exception do raise EWMICollector.CreateFmt(' Error getting WMI Class "\\%s\%s\%s": %s' ,[aHost,aRoot,aWMIClass,e.Message]);
169
+ end ;
170
+ end ;
171
+
172
+ { TWMIInstance }
173
+
174
+ constructor TWMIInstance.Create(const aInstanceName : string; aWMIItem: OleVariant);
175
+ begin
176
+ fInstance := aInstanceName;
177
+ fWMIItem := aWMIItem;
178
+ end ;
179
+
180
+ destructor TWMIInstance.Destroy;
181
+ begin
182
+ fWMIItem := Unassigned;
183
+ inherited ;
184
+ end ;
185
+
186
+ function TWMIInstance.GetName : string;
187
+ begin
188
+ Result := fInstance;
189
+ end ;
190
+
191
+ function TWMIInstance.GetProperties (const aProperties : TArray<string>) : IList<TFlexPair>;
192
+ var
193
+ prop : string;
194
+ begin
195
+ Result := TxList<TFlexPair>.Create;
196
+ for prop in aProperties do
197
+ begin
105
198
try
106
- objWMIService := GetObject(Format(' winmgmts:\\%s\%s' ,[aWMIHost,aRoot]));
107
- colItems := objWMIService.ExecQuery(Format(' SELECT * FROM %s' ,[aWMIClass]),' WQL' ,0 );
108
- oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
109
- while oEnum.Next(1 , colItem, iValue) = 0 do
110
- begin
111
- Result := colItem.Properties_.Item(aWMIProperty, 0 );
112
- Break;
113
- end ;
199
+ Result.Add(TFlexPair.Create(prop,fWMIItem.Properties_.Item(prop, 0 )));
114
200
except
115
- on E : Exception do raise EWMICollector.CreateFmt(' Error getting WMI property: %s ' ,[e.Message ]);
201
+ on E : Exception do raise EWMICollector.CreateFmt(' Retrieving "%s" (%s) ' ,[prop,e.message ]);
116
202
end ;
117
- finally
118
- CoUninitialize;
119
203
end ;
120
204
end ;
121
205
122
- class function TWMICollector.GetPropertyInstances (const aWMIHost, aRoot, aWMIClass,aWMIProperty : string; const aInstances : string = ' *' ) : TFlexPairArray;
206
+ function TWMIInstance.GetProperty (const aPropertyName: string): TFlexValue;
207
+ begin
208
+ Result := fWMIItem.Properties_.Item(aPropertyName, 0 );
209
+ end ;
210
+
211
+ { TWMIClass }
212
+
213
+ constructor TWMIClass.Create(aWMIService : OleVariant; const aClassName : string; aWMIClassItems : IEnumvariant);
214
+ begin
215
+ fWMIService := aWMIService;
216
+ fClassName := aClassName;
217
+ fWMIClassItems := aWMIClassItems;
218
+ end ;
219
+
220
+ destructor TWMIClass.Destroy;
221
+ begin
222
+ // fWMIClassItems := nil;
223
+ fWMIService := Unassigned;
224
+ inherited ;
225
+ end ;
226
+
227
+ function TWMIClass.GetInstance (const aInstance: string): IWMIInstance;
123
228
var
124
- objWMIService : OLEVariant;
125
- colItems : OLEVariant;
126
- colItem : OLEVariant;
127
- oEnum : IEnumvariant;
229
+ propItem : OLEVariant;
128
230
iValue : LongWord;
231
+ instanceName : string;
129
232
begin
130
- CoInitialize(nil );
131
- try
233
+ while fWMIClassItems.Next(1 , propItem, iValue) = 0 do
234
+ begin
235
+ instanceName := GetInstanceName(propItem);
132
236
try
133
- objWMIService := GetObject(Format(' winmgmts:\\%s\%s' ,[aWMIHost,aRoot]));
134
- colItems := objWMIService.ExecQuery(Format(' SELECT * FROM %s' ,[aWMIClass]),' WQL' ,0 );
135
- oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
136
- while oEnum.Next(1 , colItem, iValue) = 0 do
237
+ if CompareText(aInstance,instanceName) = 0 then
137
238
begin
138
- if (aInstances = ' *' ) or (CompareText(aInstances,colItem.Name ) = 0 ) then
139
- begin
140
- Result.Add(colItem.Name ,colItem.Properties_.Item(aWMIProperty, 0 ));
141
- end ;
239
+ Result := TWMIInstance.Create(instanceName,propItem);
240
+ Break;
142
241
end ;
143
- except
144
- on E : Exception do raise EWMICollector.CreateFmt(' Error getting WMI property: %s' ,[e.Message]);
242
+ finally
243
+ propItem := Unassigned;
244
+ end ;
245
+ end ;
246
+ end ;
247
+
248
+ function TWMIClass.GetInstanceName (aWMIClass : OleVariant) : string;
249
+ var
250
+ qualifiers : OleVariant;
251
+ enumQualif : IEnumVariant;
252
+ qualifItem : OleVariant;
253
+ pceltFetched : Cardinal;
254
+ propItem : OleVariant;
255
+ enumProp : IEnumVariant;
256
+ iValue : Cardinal;
257
+ properties : OleVariant;
258
+ objSWbemObjectSet : OleVariant;
259
+ begin
260
+ Result := ' ' ;
261
+ objSWbemObjectSet:= fWMIService.Get(fClassName, wbemFlagUseAmendedQualifiers and wbemFlagReturnWhenComplete);
262
+ properties := objSWbemObjectSet.Properties_;
263
+ enumProp := IUnknown(properties._NewEnum) as IENumVariant;
264
+ while enumProp.Next(1 , propItem, iValue) = 0 do
265
+ begin
266
+ qualifiers := propItem.Qualifiers_;
267
+ enumQualif := IUnknown(qualifiers._NewEnum) as IEnumVariant;
268
+ // iterate over the qualifiers
269
+ while enumQualif.Next(1 , qualifItem, pceltFetched) = 0 do
270
+ begin
271
+ // check the name of the qualifier
272
+ // Result := rgvarQualif.Name;
273
+ // Result := rgvarQualif.Value;
274
+ if qualifItem.Name = ' key' then
275
+ begin
276
+ if qualifItem.Value then if Result = ' ' then Result := aWMIClass.Properties_.Item(propItem.Name ,0 )
277
+ else Result := Format(' %s %s' ,[Result,aWMIClass.Properties_.Item(propItem.Name ,0 )]);
278
+ end ;
279
+ // VarClear(qualifItem);
280
+ qualifItem := Unassigned;
281
+ end ;
282
+ // enumQualif := nil;
283
+ qualifiers := Unassigned;
284
+ propItem := Unassigned;
285
+ end ;
286
+ // enumProp := nil;
287
+ properties := Unassigned;
288
+ objSWbemObjectSet := Unassigned;
289
+ end ;
290
+
291
+ function TWMIClass.GetInstances (const aInstances: TArray<string>): TWMIInstances;
292
+ var
293
+ propItem : OLEVariant;
294
+ iValue : LongWord;
295
+ getAllInstances : Boolean;
296
+ instanceName : string;
297
+ begin
298
+ getAllInstances := (High(aInstances) = 0 ) and (aInstances[0 ] = ' *' );
299
+ while fWMIClassItems.Next(1 , propItem, iValue) = 0 do
300
+ begin
301
+ instanceName := GetInstanceName(propItem);
302
+ if (getAllInstances) or (StrInArray(instancename,aInstances)) then
303
+ begin
304
+ Result := Result + [TWMIInstance.Create(instanceName,propItem)];
145
305
end ;
146
- finally
147
- CoUninitialize;
306
+ propItem := Unassigned;
148
307
end ;
149
308
end ;
150
309
0 commit comments