WMI Delphi
От: lka_76  
Дата: 24.05.06 09:17
Оценка:
Добрый день!
пытаюсь научиться работать с 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??
здесь на форуме находил похожие темы, но они тоже "старые" и не понятно как была решена проблема...
Re: WMI Delphi
От: alive Россия  
Дата: 24.05.06 09:59
Оценка:
Здравствуйте, 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;
...<< RSDN@Home 1.2.0 alpha rev. 649>>
...Foobar {silent}
Keep yourself alive
Re[2]: WMI Delphi
От: lka_76  
Дата: 24.05.06 10:53
Оценка:
Здравствуйте, alive, Вы писали:


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 WMI Scripting похожего...
может у меня не все установлено?? (хотя Microsoft да и везде пишет что в 2000 все встроено..)
подскажите если встать на Microsoft WMI Scripting там ниже будет путь.. может его сообщите я тогда попытаюсь добавить...
Re[3]: WMI Delphi
От: alive Россия  
Дата: 24.05.06 11:48
Оценка:
Здравствуйте, lka_76, Вы писали:

_>может у меня не все установлено?? (хотя Microsoft да и везде пишет что в 2000 все встроено..)

_>подскажите если встать на Microsoft WMI Scripting там ниже будет путь.. может его сообщите я тогда попытаюсь добавить...

Насчет Win2000 — не знаю, под рукой нет чтобы проверить. У меня импортируется из $(WINDOWS)\SYSTEM32\wbem\wbemdisp.tlb.
...<< RSDN@Home 1.2.0 alpha rev. 649>>
...Foobar {silent}
Keep yourself alive
Re[4]: WMI Delphi
От: lka_76  
Дата: 25.05.06 09:36
Оценка:
Здравствуйте, 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 практически ни какой разницы в коде...
Re[5]: WMI Delphi
От: alive Россия  
Дата: 25.05.06 10:08
Оценка:
Здравствуйте, lka_76, Вы писали:

_>подскажите как тогда перевест ина Delphi следующий кусок кода:

_>
_> objDomain = GetObject('WinNT://' + $domain + ',domain')
_> objDomain.Filter=filter
_> For Each objComputer In $objDomain
_> ......
_>

_>хотя в принципе это уже получается ADSI, но с точки зрения VB практически ни какой разницы в коде...

Честно говоря, я совсем не в теме по работе с Active Directory. В приведенном коде используется Scripting API for WMI. Почитайте справку по этой теме. Там все просто но нужно представлять предметную область. Пример получения обьекта, коллекции объектов и свойств я уже приводил.
Keep yourself alive
Re[2]: WMI Delphi
От: lka_76  
Дата: 29.05.06 04:24
Оценка:
Здравствуйте, alive

продолжаю разбараться..
получается но не все..
подскажите а как разобраться с 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 и все...
Re[3]: WMI Delphi
От: lka_76  
Дата: 29.05.06 05:13
Оценка:
Здравствуйте, lka_76, Вы писали:

извиняюсь вопрос снят...
называется не верь примерам .... хотя там и красиво написано
как оказалось нужно писать


_>      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];
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.