Добрый день!
пытаюсь научиться работать с WMI на Delphi.
столкнулся с проблемами:
нашел много инструкци, примеров по этой теме но: >> Для начала импортируйте библиотеку типов (wmi начиная с NT4SP4 встроен в систему) >> 1.Active DS Type Library ---- нет у меня такого имею WIN 2K как называется dll/ocx?? >> 2.Microsoft WMI Scripting v1.1 Library >> используйтте TSWbemLocator
советуют установить WMIcore но он только для NT4
соответсвенно не могу ни как с этим рабоатать где только не пыался найти....
большенство ссылок 2004года и не рабочии..
не помню где нашел
const STGM_default =STGM_READWRITE + STGM_SHARE_EXCLUSIVE;
STGM_BASE =STGM_READ + STGM_SHARE_EXCLUSIVE;
function getobject(const name:string;accs:dword=STGM_default):variant;
var err:HResult;
bo:tBINDOPTS;
res:IDispatch;
nm:widestring;
begin nm := name; fillchar(bo,sizeof(bo),0);
with bo do begin cbStruct := sizeof(bo);
grfFlags := BIND_MAYBOTHERUSER;
grfMode := accs;
end;
err:=CoGetObject( @nm[1] , @bo , IDispatch , @res );
OleCheck(err);
result:=res;
end;
procedure TForm1.Button1Click(Sender: TObject);
var q1,Boards,q3:variant;
begin
q1:=getobject('winmgmts:{impersonationLevel=impersonate}!//.\root\cimv2');
Bouards:=q1.ExecQuery('select * from Win32_BaseBoard', , 48);
end;
отрабатывает без проблем.. вот только не знаю что делать дальше...
в VB там дальше
For Each Board In Boards
но тогда как это реализовать на Delphi??
здесь на форуме находил похожие темы, но они тоже "старые" и не понятно как была решена проблема...
Здравствуйте, lka_76, Вы писали:
_>Добрый день! _>пытаюсь научиться работать с WMI на Delphi. _>столкнулся с проблемами:
А что конкретно вам не понятно? Как импортировать библиотеку типов?
В Delphi Project -> Import Type Library... В открывшемся окне в списке выбираем Microsoft WMI Scripting V1.2 Library(Version 1.2)
(Версия у вас может отличаться). Давим кнопку Create Unit. У меня после этого образовался юнит WbemScripting_TLB.pas.
Запрос 'select * from Win32_BaseBoard' возвращает коллекцию объектов Win32_BaseBoard. Поэтому к элементам нужно обращатся через энумератор. Вот пример который перечисляет и выводит в листбокс все свойства первой Win32_BaseBoard.
procedure TMainForm.Run;
var
Service: ISWbemServices;
ObjectSet: ISWbemObjectSet;
SObject: ISWbemObject;
PropSet: ISWbemPropertySet;
SProp: ISWbemProperty;
PropEnum, Enum: IEnumVariant;
TempObj, PropVal: OleVariant;
Value: Cardinal;
LI: TListItem;
vt: TVarType;
begin
LVProp.Items.Clear;
SWbemLocator:= TSWbemLocator.Create(Nil);
try
SWbemLocator:= TSWbemLocator.Create(Self);
Service:= SWbemLocator.ConnectServer('.', 'root\CIMV2', '', '', '', '', 0, nil);
SObject:= Service.Get('Win32_BaseBoard', wbemFlagUseAmendedQualifiers, nil);
ObjectSet:= SObject.Instances_(0, nil);
Enum:= (ObjectSet._NewEnum) as IEnumVariant;
Enum.Next(1, TempObj, Value);
SObject:= IUnknown(TempObj) as SWBemObject;
PropSet := SObject.Properties_;
PropEnum := (PropSet._NewEnum) as IEnumVariant;
while (PropEnum.Next(1, TempObj, Value) = S_OK) do
begin
SProp:= IUnknown(TempObj) as SWBemProperty;
LI:= LVProp.Items.Add;
LI.Caption:= SProp.Name;
PropVal:= SProp.Get_Value;
if PropVal <> Null then
LI.SubItems.Add(PropVal)
else
LI.SubItems.Add('-');
end;
finally
SWbemLocator.Free;
end;
end;
A>А что конкретно вам не понятно? Как импортировать библиотеку типов? A>В Delphi Project -> Import Type Library... В открывшемся окне в списке выбираем Microsoft WMI Scripting V1.2 Library(Version 1.2) A>(Версия у вас может отличаться). Давим кнопку Create Unit. У меня после этого образовался юнит WbemScripting_TLB.pas.
заходим Delphi Project -> Import Type Library
В открывшемся окне видим большой список (отсортирован по алфавиту)
смотрим куча Microsoft...
смотрим Microsoft W....
вижу
Microsoft Windows Common Controls 5.0 (SP2) (Version 1.2)
Microsoft Windows Common Controls 6.0 (SP4) (Version 2.0)
Microsoft Windows Common Controls-2 5.0 (SP2) (Version 1.2)
Microsoft Windows Common Controls-2 6.0 (SP4) (Version 2.0)
Msie ActiveX Control module (Version 1.0)
нет ни чего на Microsoft WMI Scripting похожего...
может у меня не все установлено?? (хотя Microsoft да и везде пишет что в 2000 все встроено..)
подскажите если встать на Microsoft WMI Scripting там ниже будет путь.. может его сообщите я тогда попытаюсь добавить...
Здравствуйте, lka_76, Вы писали:
_>может у меня не все установлено?? (хотя Microsoft да и везде пишет что в 2000 все встроено..) _>подскажите если встать на Microsoft WMI Scripting там ниже будет путь.. может его сообщите я тогда попытаюсь добавить...
Насчет Win2000 — не знаю, под рукой нет чтобы проверить. У меня импортируется из $(WINDOWS)\SYSTEM32\wbem\wbemdisp.tlb.
Здравствуйте, alive, Вы писали:
A>Здравствуйте, lka_76, Вы писали:
_>>может у меня не все установлено?? (хотя Microsoft да и везде пишет что в 2000 все встроено..) _>>подскажите если встать на Microsoft WMI Scripting там ниже будет путь.. может его сообщите я тогда попытаюсь добавить...
A>Насчет Win2000 — не знаю, под рукой нет чтобы проверить. У меня импортируется из $(WINDOWS)\SYSTEM32\wbem\wbemdisp.tlb.
Извиняюсь действительно я тупил....
вместо Delphi Project -> Import Type Library я искал в Component -> Import ActiveX Control
это решает большенство моих проблем...
подскажите как тогда перевест ина Delphi следующий кусок кода:
objDomain = GetObject('WinNT://' + $domain + ',domain')
objDomain.Filter=filter
For Each objComputer In $objDomain
......
хотя в принципе это уже получается ADSI, но с точки зрения VB практически ни какой разницы в коде...
Здравствуйте, lka_76, Вы писали:
_>подскажите как тогда перевест ина Delphi следующий кусок кода: _>
_> objDomain = GetObject('WinNT://' + $domain + ',domain')
_> objDomain.Filter=filter
_> For Each objComputer In $objDomain
_> ......
_>
_>хотя в принципе это уже получается ADSI, но с точки зрения VB практически ни какой разницы в коде...
Честно говоря, я совсем не в теме по работе с Active Directory. В приведенном коде используется Scripting API for WMI. Почитайте справку по этой теме. Там все просто но нужно представлять предметную область. Пример получения обьекта, коллекции объектов и свойств я уже приводил.
продолжаю разбараться..
получается но не все..
подскажите а как разобраться с Win32_NetworkAdapterConfiguration делаю анологично примеру...
получаю 8 сеетвых адаптеров ! и все это в куче... т.е примерно 8*60=480 свойств.. а мне нужно всего 2*8, ито если активны...
реально всего 2 (иногда 4 это когда 2 сетевых карты) MACAddress и IPAddress...
причем MAC получается без проблем... а вот IP непонятно.. теоритически это массив при отладке пишет что array of Varian... но
VarArrayHighBound(SProp.Get_Value, 1) возвращает 0....
использую следующий код (взял из примера только заменил на Win32_NetworkAdapterConfiguration):
procedure TForm1.Button1Click(Sender: TObject);
var
Service: ISWbemServices;
ObjectSet: ISWbemObjectSet;
SObject: ISWbemObject;
PropSet: ISWbemPropertySet;
SProp: ISWbemProperty;
PropEnum, Enum: IEnumVariant;
TempObj: OleVariant;
Value: Cardinal;
Column: TListColumn;
begin
Memo1.Lines.Clear;
Service := SWbemLocator1.ConnectServer('.', 'root\CIMV2', '', '', '', '', 0, nil);
SObject := Service.Get('Win32_NetworkAdapterConfiguration', wbemFlagUseAmendedQualifiers, nil);
ObjectSet := SObject.Instances_(0, nil);
Enum := (ObjectSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, TempObj, Value) = S_OK) do
begin
SObject := IUnknown(TempObj) as SWBemObject;
PropSet := SObject.Properties_;
PropEnum := (PropSet._NewEnum) as IEnumVariant;
while (PropEnum.Next(1, TempObj, Value) = S_OK) do
begin
SProp := IUnknown(TempObj) as SWBemProperty;
Memo1.Lines.Add('***'+SProp.Name);
ShowProp(SProp);
end;
end; { while }end;
procedure TForm1.ShowProp(SProp: ISWbemProperty);
var
StrValue: string;
Count: Cardinal;
begin
StrValue := '';
Memo1.Lines.Add('SProp.CIMType'+IntToStr(SProp.CIMType));
if VarIsNull(SProp.Get_Value) then
StrValue := '!!Пусто!!'else
case SProp.CIMType of//******************************************************************//
wbemCimtypeUint8, wbemCimtypeSint8, wbemCimtypeUint16, wbemCimtypeSint16,
wbemCimtypeUint32, wbemCimtypeSint32, wbemCimtypeSint64:
if VarIsArray(SProp.Get_Value) then
begin
if VarArrayHighBound(SProp.Get_Value, 1) <> 0 then
for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do
StrValue := StrValue + ' ' + IntToStr(SProp.Get_Value[Count]);
end
else
StrValue := IntToStr(SProp.Get_Value);
//******************************************************************//
wbemCimtypeReal32, wbemCimtypeReal64:
StrValue := FloatToStr(SProp.Get_Value);
//******************************************************************//
wbemCimtypeString:
if VarIsArray(SProp.Get_Value) then
begin
if VarArrayHighBound(SProp.Get_Value, 1) <> 0 then
for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do
StrValue := StrValue + ' ' + SProp.Get_Value[Count];
end
else
StrValue := SProp.Get_Value;
//…
//******************************************************************//else begin
StrValue:='-неизвестный тип';
end;
end; {case}
Memo1.Lines.Add(StrValue);
end;
при отладке попадаем
wbemCimtypeString:
if VarIsArray(SProp.Get_Value) then
begin
if VarArrayHighBound(SProp.Get_Value, 1) <> 0 then //здесь False и все...
извиняюсь вопрос снят...
называется не верь примерам .... хотя там и красиво написано
как оказалось нужно писать
_> wbemCimtypeString:
_> if VarIsArray(SProp.Get_Value) then
_> begin
_> if VarArrayHighBound(SProp.Get_Value, 1) <> 0 then
_> for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do
_> StrValue := StrValue + ' ' + SProp.Get_Value[Count];
_> end
for Count := VarArrayLowBound(SProp.Get_Value, 1) to VarArrayHighBound(SProp.Get_Value, 1) do
StrValue := StrValue + ' ' + SProp.Get_Value[Count];