如何使用WMI与Delphi没有大幅增加应用程序的文件大小? [英] How do I use WMI with Delphi without drastically increasing the application's file size?
问题描述
我使用的是Delphi 2010,当我创建一个打印Hello World的控制台应用程序时,它需要111 kb。如果我想用Delphi查询WMI,我将WBEMScripting_TLB,ActiveX和Variants单元添加到我的项目中。如果我执行一个简单的WMI查询,我的可执行文件大小跳到810 kb。我
I am using Delphi 2010, and when I created a console application that prints "Hello World", it takes 111 kb. If I want to query WMI with Delp I add WBEMScripting_TLB, ActiveX, and Variants units to my project. If I perform a simple WMI query, my executable size jumps to 810 kb. I
有没有这样大量的文件大小来查询WMI?原谅我的无知,但为什么我没有C ++的这个问题?
Is there anyway to query WMI without such a large addition to the size of the file? Forgive my ignorance, but why do I not have this issue with C++?
这是我的代码:
program WMITest;
{$APPTYPE CONSOLE}
uses
SysUtils,
WBEMScripting_TLB,
ActiveX,
Variants;
function GetWMIstring(wmiHost, root, wmiClass, wmiProperty: string): string;
var
Services: ISWbemServices;
SObject: ISWbemObject;
ObjSet: ISWbemObjectSet;
SProp: ISWbemProperty;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OLEVariant;
loc: TSWbemLocator;
SN: string;
i: integer;
begin
Result := '';
i := 0;
try
loc := TSWbemLocator.Create(nil);
Services := Loc.ConnectServer(wmiHost, root {'root\cimv2'}, '', '', '', '',
0, nil);
ObjSet := Services.ExecQuery('SELECT * FROM ' + wmiClass, 'WQL',
wbemFlagReturnImmediately and wbemFlagForwardOnly, nil);
Enum := (ObjSet._NewEnum) as IEnumVariant;
if not VarIsNull(Enum) then
try
while Enum.Next(1, TempObj, Value) = S_OK do
begin
try
SObject := IUnknown(TempObj) as ISWBemObject;
except SObject := nil;
end;
TempObj := Unassigned;
if SObject <> nil then
begin
SProp := SObject.Properties_.Item(wmiProperty, 0);
SN := SProp.Get_Value;
if not VarIsNull(SN) then
begin
if varisarray(SN) then
begin
for i := vararraylowbound(SN, 1) to vararrayhighbound(SN, 1) do
result := vartostr(SN[i]);
end
else
Result := SN;
Break;
end;
end;
end;
SProp := nil;
except
Result := '';
end
else
Result := '';
Enum := nil;
Services := nil;
ObjSet := nil;
except
on E: Exception do
Result := e.message;
end;
end;
begin
try
WriteLn('hello world');
WriteLn(GetWMIstring('.', 'root\CIMV2', 'Win32_OperatingSystem',
'Caption'));
WriteLn('done');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
更新:
当我编译以下来自MSDN的示例与Microsoft Visual C ++ 2008(控制台应用程序),它是76 kb。
UPDATE: When I compile the following sample from MSDN with Microsoft Visual C++ 2008 (console application), it is 76 kb.
推荐答案
@Mick,您可以访问WMI而不从Delphi导入WBEMScripting,使用 IBindCtx 和 IMoniker 界面。
@Mick, you can access the WMI without import the WBEMScripting from Delp using the IBindCtx and IMoniker interfaces.
检查这个简单的代码(在Delphi 2010和Windows 7中测试),exe文件大小为174 kb。
Check this simple code (Tested in Delphi 2010 and Windows 7), the exe file size is 174 kb.
program WmiTest;
{$APPTYPE CONSOLE}
uses
SysUtils
,ActiveX
,ComObj
,Variants;
function GetWMIstring(wmiHost, root, wmiClass, wmiProperty: string): string;
var
objWMIService : OLEVariant;
colItems : OLEVariant;
colItem : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
function GetWMIObject(const objectName: String): IDispatch;
var
chEaten: Integer;
BindCtx: IBindCtx;//for access to a bind context
Moniker: IMoniker;//Enables you to use a moniker object
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));//Converts a string into a moniker that identifies the object named by the string
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));//Binds to the specified object
end;
begin
objWMIService := GetWMIObject(Format('winmgmts:\\%s\%s',[wmiHost,root]));
colItems := objWMIService.ExecQuery(Format('SELECT * FROM %s',[wmiClass]),'WQL',0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
while oEnum.Next(1, colItem, iValue) = 0 do
begin
Result:=colItem.Properties_.Item(wmiProperty, 0); //you can improve this code ;) , storing the results in an TString.
end;
end;
begin
try
CoInitialize(nil);
try
WriteLn(GetWMIstring('.', 'root\CIMV2', 'Win32_OperatingSystem','Caption'));
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
Begin
Writeln(E.Classname, ': ', E.Message);
Readln;
End;
end;
end.
这篇关于如何使用WMI与Delphi没有大幅增加应用程序的文件大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!