Работа с процессами и потоками в WMI



В WMI каждому запущенному в системе процессу соответствует экземпляр класса Win32_Process.

Основные свойства класса Win32_Process:

Caption – короткое текстовое описание процесса;

CommandLine – командная строка, используемая для запуска процесса;

CreationDate – время начала выполнения процесса;

Description – полное описание процесса;

ExecutablePath – полный путь к исполняемому файлу процесса;

HandleCount – общее количество дескрипторов, открытых в настоящее время процессом;

MaximumWorkingSetSize – максимально возможное количество страниц памяти доступное процессу;

MinimumWorkingSetSize – минимально возможное количество страниц памяти доступное процессу;

Name – имя процесса;

PageFileUsage – объем части файла подкачки, которая используется процессом в настоящее время;

ParentProcessId – идентификатор родительского процесса;

PeakPageFileUsage – максимальный объем части файла подкачки, которая использовалась процессом за время его работы;

PeakVirtualSize – максимальное значение объема виртуального адресного пространства, которое использовалось процессом единовременно;

PeakWorkingSetSize – максимальный объем физической памяти, используемый процессом;

Priority – приоритет процесса;

ProcessId – идентификатор процесса;

ReadOperationCount – число выполненных процессом операций чтения;

ReadTransferCount – объем прочитанных данных;

ThreadCount – число активных потоков в процессе;

VirtualSize – текущий объем виртуального адресного пространства в байтах, используемого процессом;

WorkingSetSize – размер физической памяти в байтах, необходимый для выполнения процесса;

WriteOperationCount – число выполненных процессом операций записи;

WriteTransferCount – объем записанных данных.

 

 

Основные методы класса Win32_Process.

AttachDebugger() – запускает отладчик, установленный в системе по умолчанию, для отладки процесса, возвращает 0 – при успешном выполнении или код ошибки в противном случае.

Create(CommandLine, CurrentDirectory, ProcessStartupInformation, ProcessId) – создает новый процесс, возвращает 0 в случае успешного создания объекта или другое число в случае ошибки.

SetPriority(Priority) – устанавливает приоритет процесса, параметр Priority определяет требуемый приоритет и может принимать следующие значения:

64 (0x40) – Idle – низкий,

16384 (0x4000) – Below Normal – ниже среднего (Win2000/XP/2003),

32 (0x20) - Normal – средний,

32768 (0x8000) – Above Normal – выше среднего (Win2000/XP/2003),

128 (0x80) – High – высокий,

256 (0x100) – Realtime – наивысший;

возвращает 0 – при успешном выполнении или код ошибки в противном случае.

Terminate(Reason) – завершает процесс и все его потоки, числовой код Reason задает код выхода, который будет сообщен операционной системе после завершения процесса, возвращает 0 – при успешном выполнении или код ошибки в противном случае.

 

Для указания начальных параметров запуска процесса используется класс Win32ProcessStartup.

Основные свойства класса Win32_ProcessStartup:

PriorityClass – приоритет нового процесса;

ShowWindow – способ отображения окна программы;

0 – SW_HIDE – скрытое окно,

1 – SW_NORMAL – окно отображается и активируется,

2 – SW_SHOWMINIMIZED – окно отображается свернутым и активируется,

3 – SW_SHOWMAXIMIZED – окно отображается развернутым и активируется,

4 – SW_SHOWNOACTIVATE – окно отображается но не активируется;

X – отступ для окна программы в пикселях по горизонтали от верхнего левого угла;

Y – отступ для окна программы в пикселях по вертикали от верхнего левого угла;

XSize – ширина окна в пикселях;

YSize – высота окна в пикселях.

 

Для представления информации о потоках в WMI используется класс Win32_Thread.

Основные свойства класса Win32_Thread:

ElapsedTime – общее время выполнения выделенное потоку;

Priority – динамический приоритет потока;

PriorityBase – базовый приоритет потока;

ProcessHandle – идентификатор процесса, создавшего поток;

ThreadState – текущее состояние потока:

0 – Initialized – создание,

1 – Ready – готовность,

2 – Running – выполнение,

3 – Standby – поток выбран для выполнения,

4 – Terminated – завершение,

5 – Waiting – ожидание,

6 – Transition – ожидание освобождения стека ядра,

7 – Unknown – неизвестное состояние;

ThreadWaitReason – причина ожидания (определено при ThreadState=6).

 

Рассмотрим использование некоторых методов класса Win32_Process на примерах. В листингах 3 и 4 приведены примеры сценариев создания процесса с помощью метода Create(). В листинге 5 приведен пример сценария уничтожающего все процессы "notepad.exe" с помощью метода Terminate().

 

Листинг 3. Запуск процесса “notepad.exe”

set obj = GetObject("WinMgmts:Win32_Process")

err = obj.Create("notepad.exe", null, _

null, ProcessId)

 

В первой строке этого сценария получаем доступ к классу Win32_Process. Во второй строке создается новый процесс "notepad.exe". После создания процесса в переменной будет ProcessId содержаться идентификатор нового процесса.

 

Листинг 4. Запуск процесса “notepad.exe” с указанием начальных параметров запуска

set WMI = GetObject("WinMgmts:")

set objStartup = WMI.Get("Win32_ProcessStartup")

set objConfig = objStartup.SpawnInstance_

objConfig.ShowWindow = 3

set objProcess = WMI.Get ("Win32_Process")

err = objProcess.Create("notepad.exe", null, _

objConfig, ProcessId)

Здесь во второй строке с помощью метода SwbemServices.Get() получаем указатель на объект SwbemObject соответствующий классу Win32_ProcessStartup. Далее, с помощью метода SpawnInstance_() объекта SwbemObject создается новый объект соответствующего класса. Затем задается свойство ShowWindow этого объекта и создается новый процесс “notepad.exe”.

 

Листинг 5. Удаление всех процессов “notepad.exe”

set WMI = GetObject("WinMgmts:")

set objs = WMI.ExecQuery _

("SELECT * FROM Win32_Process " & _

"WHERE Name = 'notepad.exe'")

for each obj in objs

obj.Terminate()

next

 

В строке 2 данного примера используется метод ExecQuery объекта SwbemServices. Данный метод с помощью запроса на языке WQL (WMI Query Language), который является подмножеством стандартного языка ANSI SQL, формирует коллекцию экземпляров класса Win32_Process. Далее в цикле for для каждого объекта из этой коллекции выполняется метод Terminate().

 

Обработка событий в WMI

 

Внутри WMI реализована служба работы с событиями - WMI Event Service. Эта служба поддерживает фильтрацию событий и обеспечение их обработки.

Для того чтобы зарегистрировать событие и иметь возможность его обрабатывать, необходимо при помощи метода ExecNotificationQuery объекта SWbemServices выполнить запрос WQL по специальной форме, например:

Set colMonitorProcess = _

 objWMIService.ExecNotificationQuery _

 ("SELECT * FROM __InstanceOperationEvent " & _

 "WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")

Данный WQL запрос возвращает экземпляры класса __InstanceOperationEvent (с двумя подчеркиваниями), которые формируются при каждом создании, удалении или модификации экземпляра WMI класса. Оператор WITHIN определяет интервал времени в секундах между опросами. WITHIN 1 говорит о том, что опрос будет производиться каждую секунду. С помощью конструкции WHERE происходит фильтрация события, при этом оператор ISA указывает необходимые события. В приведенном выше примере происходит фильтрация событий, для которых свойство TargetInstance класса __InstanceOperationEvent это экземпляр класса Win32_Process.

Класс __InstanceOperationEvent является родительским для всех событий вызываемых экземплярами WMI классов. Потомки этого класса:

__InstanceCreationEvent – появляется (создается) при создании нового экземпляра WMI класса;

__InstanceModificationEvent – создается при модификации существующего экземпляра класса;

__InstanceDeletionEvent – создается при уничтожении экземпляра класса.

При запросе __InstanceOperationEvent возвращаются все экземпляры этих трех классов.

Метод ExecNotificationQuery возвращает объект класса SWbemEventSource, в котором описан единственный метод NextEvent. Этот метод ожидает появления события, удовлетворяющего условию запроса, и при его появлении, возвращает стандартный объект SWbemObject, который представляет событие. Для получения доступа к объекту, который вызвал это событие, используется его свойство TargetInstance (Листинг 6).

 

Листинг 6. Обработка одиночного события.

Set objWMIService = GetObject("winmgmts:")

Set colMonitorProcess = _

 objWMIService.ExecNotificationQuery _

("SELECT * FROM __InstanceOperationEvent " _

& " WITHIN 1 WHERE TargetInstance ISA " _

& "'Win32_Process'")

WScript.Echo "Ожидание события ..."

Set objLatestEvent = colMonitorProcess.NextEvent

WScript.Echo objLatestEvent.Path_.Class

Wscript.Echo "Process Name: " & _

 objLatestEvent.TargetInstance.Name

Wscript.Echo "Process ID: " & _

 objLatestEvent.TargetInstance.ProcessId

WScript.Echo "Time: " & Now

 

В сценарии (Листинг 6) происходит ожидание наступления первого события, вызванного созданием, модификацией, либо удалением экземпляра класса Win32_Process; выводится имя класса события, информация о процессе, вызвавшем событие и время. В данном сценарии происходит обработка только одного события. Для того чтобы опрос происходи постоянно, необходимо поместить в сценарий бесконечный цикл (Листинг 7).

 

Листинг 7. Обработка событий в цикле.

Set objWMIService = GetObject("winmgmts:")

Set colMonitorProcess = _

 objWMIService.ExecNotificationQuery _

("SELECT * FROM __InstanceOperationEvent " _

& " WITHIN 1 WHERE TargetInstance ISA " _

& "'Win32_Process'")

WScript.Echo "Ожидание события ..."

Do

 Set objLatestEvent = colMonitorProcess.NextEvent

 WScript.Echo objLatestEvent.Path_.Class

 Wscript.Echo "Process Name: " & _

objLatestEvent.TargetInstance.Name

 Wscript.Echo "Process ID: " & _

objLatestEvent.TargetInstance.ProcessId

 WScript.Echo "Time: " & Now

Loop

Запуск таких сценариев необходимо выполнять в консольном режиме. Для завершения – нажать комбинацию клавиш Ctrl+C.

 

Сбор информации о памяти

 

Основную информацию об общем и свободном объеме физической и виртуальной памяти можно получить с помощью класса Win32_OperatingSystem. Основные свойства этого класса, содержащие информацию о памяти следующие:

FreePhysicalMemory – объем свободной физической памяти;

FreeSpaceInPagingFiles – объем памяти в страничных файлах доступный без выгрузки страниц;

FreeVirtualMemory – объем свободной виртуальной памяти;

MaxProcessMemorySize – максимальный объем памяти, который может занять процесс.

SizeStoredInPagingFiles – общий объем информации, который может быть сохранен в страничных файлах;

TotalSwapSpaceSize – общий объем памяти в страничных файлах;

TotalVirtualMemorySize – общий объем виртуальной памяти.

Информация о банках физической памяти отображена в классе Win32_PhysicalMemory. В свойстве Capacity данного класса хранится объем одного банка физической памяти.

Страничные файлы в WMI представлены экземплярами класса Win32_PageFile. Основные свойства этого класса следующие:

Name – название страничного файла;

MaximumSize – максимальный размер страничного файла устанавливаемый пользователем; операционная система не может превысить это значение;

InitialSize – начальный размер страничного файла;

FreeSpace – объем, доступный в страничном файле.

 

Планирование заданий

 

Для планирования заданий используется класс Win32_ScheduledJob. Основные свойства этого класса:

Command – командная строка запуска программы.

DaysOfMonth – число месяца, когда задание должно выполняться. Если задание должно выполняться несколько раз в месяц, коды чисел соединяются логической операцией OR.

 

 

Таблица 1

Коды чисел месяца в свойстве DaysOfMonth

Шестнадцатеричное значение Десятичное значение Число месяца
0x1 1 1-е
0x2 2 2-е
0x4 4 3-е
0x8 8 4-е
0x10 16 5-е
0x20 32 6-е
0x40 64 7-е
0x80 128 8-е
0x100 256 9-е
0x200 512 10-е
0x400 1024 11-е
0x800 2048 12-е
0x1000 4096 13-е
0x2000 8192 14-е
0x4000 16384 15-е
0x8000 32768 16-е
0x10000 65536 17-е
0x20000 131072 18-е
0x40000 262144 19-е
0x80000 524288 20-е
0x100000 1048576 21-е
0x200000 2097152 22-е
0x400000 4194304 23-е
0x800000 8388608 24-е
0x1000000 16777216 25-е
0x2000000 33554432 26-е
0x4000000 67108864 27-е
0x8000000 134217728 28-е
0x10000000 268435456 29-е
0x20000000 536870912 30-е
0x40000000 1073741824 31-е

 

DaysOfWeek – день недели, когда задание должно выполняться. Если задание должно выполняться несколько раз в неделю, коды дней недели соединяются логической операцией OR.

Таблица 2

Коды дней недели в свойстве DaysOfWeek

Шестнадцатеричное значение Десятичное значение День недели
0x1 1 Понедельник
0x2 2 Вторник
0x4 4 Среда
0x8 8 Четверг
0x10 16 Пятница
0x20 32 Суббота
0x40 64 Воскресенье

 

InteractWithDesktop – определение задания как интерактивного. Задание называют интерактивным, если пользователь может осуществлять ввод информации в запускаемое приложение.

JobId – идентификатор задания.

RunRepeatedly – False, если задание выполняется один раз; True – если задание выполняется несколько раз в назначенные дни.

StartTime – время выполнения задания в формате “YYYYMMDDHHMMSS.MMMMMM(+-)OOO”, где “YYYYMMDD” должно быть заменено “********”, так как необходимо задать только время, без даты. “(+-)OOO” задает разницу между временем GMT и локальным временем. Для Украины это значение должно составлять “+120”. Пример: 12.30 в данном формате записывается следующим образом: “********123000.000000+120”.

В классе Win32_ScheduledJob определены методы Create и Delete для создания и удаления заданий.

Метод Create имеет следующие параметры:

Create (Command, StartTime, RunRepeatedly, DeysOfWeek, DaysOfMonth, InteractWithDesktop, JobId)

Метод Create возвращает 0 в случае успешного назначения задания и код ошибки в противном случае. Также параметр JobId служит для передачи в сценарий идентификатора созданного задания.

Метод Delete вызывается без параметров. Возвращает 0 в случае успешного удаления задания и код ошибки в противном случае.

 

Работа с файловой системой

 

Для работы с файловой системой в WMI существуют следующие классы:

Win32_LogicalDisk – для получения информации о логических дисках;

CIM_DataFile – для работы с файлами;

Win32_Directory – для работы с папками.

Основными свойствами класса Win32_LogicalDisk являются:

DeviceID – идентификатор логического диска;

DriveType – тип логического диска:

2 – сменный диск, 3 – жесткий диск, 4 – сетевой диск,

5 – CD-ROM, 6 – RAM диск;

FileSystem – тип файловой системы;

FreeSpace – объем доступного дискового пространства.

Основные свойства класса CIM_DataFile следующие:

CreationDate – дата и время создания файла;

Drive – диск, на котором хранится файл;

Extension – расширение;

FileName – простое имя файла без расширения;

FileSize – размер файла;

FileType – тип файла, ассоциированный с его расширением;

FSName – тип файловой системы;

LastAccessed – дата и время последнего доступа к файлу;

LastModified – дата и время последней модификации файла;

Name – полное имя файла;

Path – путь.

Для копирования, переименования и удаления файла класс CIM_DataFile содержит методы Copy(FileName), Rename(FileName), и Delete() соответственно.

Класс Win32_Directory содержит аналогичные свойства и методы, что и перечисленные выше свойства и методы класса CIM_DataFile.

4.2 Создание WMI приложений на C++

Введение

Создание на C++ приложений, в которых используются возможности WMI, является более сложной задачей по сравнению с использованием WMI в сценариях, написанных на скриптовых языках (VBScript или JScript). Это связано с тем, что в приложениях на C++ необходимо выполнить инициализацию COM, подключение и настройку WMI протоколов, и обеспечить корректное завершение приложения. Однако C++ имеет большую мощность и гибкость чем скриптовые языки. Таким образом, скриптовые языки предпочтительнее использовать при решении простых задач, для более серьезных приложений предпочтительнее использовать С++.

 

Любое WMI приложение должно содержать следующие части:

1. Инициализация COM.

2. Создание подключения к пространству имен WMI.

3. Установка уровней безопасности для WMI подключения.

4. Реализация функциональности приложения.

5. Очистка и корректное завершение WMI приложения.

 

Рассмотрим каждую из этих частей.

 

Инициализация COM

 

Так как WMI базируется на технологии COM, для доступа к WMI необходимо выполнить вызовы функций CoInitializeEx и CoInitializeSecurity.

Вызов CoInitializeEx это стандартная функция для установки COM интерфейса. Следующий пример (листинг 8) показывает вызов CoInitializeEx.

 

Листинг 8. Пример вызова функции CoInitializeEx:

HRESULT hr;

hr = CoInitializeEx(0, COINIT_MULTITHREADED);

if (FAILED(hr))

{

cout << "Failed to initialize COM library."

  << "Error code = 0x"

  << hex << hr << endl;

return hr;

}

 

Функция CoInitializeSecurity вводит автоматические настройки безопасности. Эти установки применяются ко всем импортируемым и экспортируемым ссылкам на объекты, за исключением явно переопределенных с использованием дополнительных вызовов API-функций. Следующий пример (листинг 9) показывает, как выполнять вызов CoInitializeSecurity.

 

Листинг 9. Пример вызова функции CoInitializeSecurity:

hr = CoInitializeSecurity(

NULL,   // Security descriptor   

-1,     // COM negotiates authentication service

NULL,   // Authentication services

NULL,  // Reserved

RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication

                         // level for proxies

RPC_C_IMP_LEVEL_IMPERSONATE,// Default Impersonation

                        // level for proxies

NULL,                 // Authentication info

EOAC_NONE,            // Additional capabilities

                        // of the client or server

  NULL);                   // Reserved

 

if (FAILED(hr))

{

cout << "Failed to initialize security.

  << "Error code = 0x"

  << hex << hr << endl;

CoUninitialize();

return hr;             // Program has failed.

}

 

После инициализации COM, следующим шагом является создания подключения к пространству имен WMI.

 


Дата добавления: 2018-05-12; просмотров: 596; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!