а вы знакомы с WMI?
несколько дней назад аббревиатура WMI мне была знакома лишь из списка служб Windows. Однако после короткого знакомства выяснилось что это весьма мощный инструмент для администрирования и получения информации о системе, причем удаленных системах в том числе. В прочем в работе с удаленными машинами это насколько я понимаю и заключается суть WMI. Меня же пока что заинтересовало лишь получение информации с локальной машины, хотя на самом деле получить информацию с удаленной ни чуть не сложнее должно быть. Итак, маленький пример использования WMI в Delphi. Чтобы получить возможность использовать WMI в Delphi необходимо импортировать библиотеку Microsoft WMI Scripting v1.x Library (wbemdisp.tbl) после чего непосредственно получим модуль с описанием интерфейсов WBEM (web-based enterprise managment). Поскольку навыков работы с WMI я не имею, то теории здесь не будет никакой (: Допустим мы хотим получить некоторую информацию о конфигурации системы, например, о процессоре, об ОС, о BIOS, о жестком диске, или посмотреть список процессов, или даже данные о производительности. Для решения подобных задач сначала необходимо подключиться к провайдеру WMI и выбрать нужную информацию опираясь на описание классов предоставляемых WMI. Для начала с помощью ISWbemLocator нам требуется подключиться к нужной машине и пространству имен, и получить экземпляр ISWbemServices с помощью которого можно выполнять действия над этим пространством имен, например выполнять запросы, для запросов используется язык WQL, весьма напоминающий SQL. Итак, services для будущих нужд занесем в private секцию формы, и получим его экземпляр при создании формы.
uses WbemScripting_TLB; ... private services : ISWbemServices; ... procedure TMainForm.FormCreate(Sender: TObject); var locator : ISWbemLocator; begin locator := CoSWbemLocator.Create(); services := locator.ConnectServer('.','root\cimv2','','','','',0,nil); end;
Метод ConnectServer содержит в качестве параметров имя (ип адрес) машины, имя пользователя пароль и т.п Допустим мы хотим получить сведения об операционной системе которые представлены классом Win32_OperatingSystem, например название, номер сборки, архитектуру, директорию системы; Информацию о процессоре Win32_Processor: название, тактовая частота в МГц, число ядер, размер кэша второго уровня в килобайтах; информацию о видеоадаптере (Win32_VideoController): название, количество памяти, режим экрана, драйверы. для хранения нужных классов и полей воспользуется sl:TStringList, в значения которого запишем sl[wmi_class_name] = field_list; Далее для всех записей из списка извлечем нужную информацию с помощью sevices. Далее разделим с помощью pl : TStringList список извлекаемых для класса полей на отдельные строки. Для каждой такой строки получим соответствуещее свойство по названию, и добавим в итоговую информацию в TValueListEditor на форме. После чего для наглядности переведем объем видеопамяти в Мбайты. Поэтому расширим обработчик создания формы следующим образом:
procedure TMainForm.FormCreate(Sender: TObject); var locator : ISWbemLocator; objectSet : ISWbemObjectSet; obj : ISWbemObject; sl,pl : TStringList; i,j:integer; wmiClass, selectList : string; propName : string; propValue : string; varProp : oleVariant; intVal : cardinal; begin locator := CoSWbemLocator.Create(); services := locator.ConnectServer('.','root\cimv2','','','','',0,nil); locator := nil; sl := TStringList.Create; pl := TStringList.Create; sl.Values['Win32_OperatingSystem'] := 'Caption, Version, OSArchitecture, WindowsDirectory'; sl.Values['Win32_Processor'] := 'Name, NumberOfCores, CurrentClockSpeed, L2CacheSize'; sl.Values['Win32_VideoController'] := 'VideoProcessor, AdapterRAM, VideoModeDescription, InstalledDisplayDrivers'; for i:=0 to sl.Count - 1 do begin wmiClass := sl.Names[i]; selectList := sl.ValueFromIndex[i]; pl.CommaText := selectList; objectSet :=services.ExecQuery('select '+ selectList + ' from ' + wmiClass,'WQL', wbemFlagReturnImmediately and wbemFlagForwardOnly,nil); obj := objectSet.ItemIndex(0); for propName in pl do begin varProp := obj.Properties_.Item(propName,0); if not varIsNull(varProp) then propValue := varToStr(varProp) else propValue := ''; valueList.Values[propName] := propValue; end; end; intVal := StrToInt(valueList.Values['AdapterRAM']); valueList.Values['AdapterRAM'] := intToStr(intVal shr 20); sl.Free; pl.Free; end;
28.04.2010 в 15:05
28.04.2010 в 20:36
Тем не менее можно изменить код следующим образом:
29.04.2010 в 15:03
"Не верный запрос"
Будем поискать проблему
P.S. Я тоже импортировал библиотеку 1.2 (Win XP SP3), Delphi 2007
29.04.2010 в 20:46
или сверить равно ли этому значение
которое передается в ExecQuery
быть может где то пробел пропущен? в 'select ' Или 'from ' например.
01.05.2010 в 14:36
И еще, в классе Win32_OperatingSystem отсутствует (у меня на компе) свойство OSArchitecture. А так все заработало.
01.05.2010 в 14:31
21.08.2011 в 22:07
Плиз, помогите.
25.08.2011 в 16:38
дабы получить список активных процессов на компе (с удаленным работа только в части коннекта должна отличаться) код будет примерно таков (здесь plw : TListView)
чтобы закрыть процесс, например блокнот, то надо его найти среди запущенных и вызвать метод terminate. тоже выглядит примерно так (коннект остается из предыдущего пункта):
а запустить новый процесс можно так:
но тут надо понимать от какого пользователя процесс будет запускаться.
19.10.2011 в 02:50
19.10.2011 в 02:55
попробуйте замените цикл for-in на обычный for.
11.01.2014 в 14:06
Но я пробую выводить список расширенных папок ('Win32_Share','Caption, Name, Path'), но он мне выводит только одну папку. Как решить этот вопрос?
Видимо где то перед перебором значения и перебором названия нужно сделать ещё один перебор на количество.
Можете помочь в этом вопросе? Delphi 7/Win 7.
11.01.2014 в 15:29
17.02.2014 в 18:09
obj := objectSet.ItemIndex(0);
помогите