MyTetra Share
Делитесь знаниями!
Python: модуль для работы с WMI
27.12.2017
18:39
Текстовые метки: Python
Раздел: Python - script-coding.com

Перейти на главную страничку сайта (список статей, файлы для скачивания)

ФОРУМ (здесь можно обсудить эту статью, а также любые проблемы программирования на различных макроязыках и в скриптовых средах)

Python: модуль для работы с WMI

This text is a rather free translation of the materials of the Tim Golden's site http://tgolden.sc.sabren.com/index.html, namely:

See also WMI Cookbook (http://tgolden.sc.sabren.com/python/wmi_cookbook.html), that has not been included here.

This material has been put here with the author's consent.


Данный текст является достаточно вольным переводом материалов сайта http://tgolden.sc.sabren.com/index.html, а именно:

Смотрите также "WMI Cookbook" ("поваренная книга WMI"), которая здесь не отражена: http://tgolden.sc.sabren.com/python/wmi_cookbook.html.

Данный материал размещён здесь с согласия автора, Тима Гольдена (Tim Golden).


Технология WMI (Windows Management Instrumentation) является реализацией от Microsoft модели управления предприятием на базе Web (Web-Based Enterprise Management, WBEM) с поддержкой схемы Common Information Model (CIM). Естественно, этот продукт от Microsoft использует DCOM как основной стержень, и поэтому, с точки зрения Питона, нуждается, например, в Win32 Extensions от Марка Хаммонда (Mark Hammond) или в любом другом коде, который сделает ту же самую работу.

Если вы установили вышеупомянутые расширения, ваша работа почти сделана. Инструментарий WMI - это иерархия объектов с некоторым количеством самодокументирования. Большинство примеров, на которые вы натолкнётесь, нацелено в VBS или WSH, но они адаптируются с достаточной лёгкостью. Однако... Как только вы перестаёте мочить пальцы ног в краешке воды и начинаете погружаться в тёмные воды, вы обнаруживаете, что не все вещи всегда так уж прямолинейны.

Модуль, который предлагается здесь, делает некоторое количество "грязной" работы, чтобы облегчить вам жизнь. Вы всегда имеете доступ к основному WMI COM-объекту в случае, если вам нужно немного "попачкать руки", а для решения насущных задач, с которыми приходится сталкиваться ежедневно, модуль может быть весьма удобен.

Copyright и лицензирование

© Тим Гольден (Tim Golden), 5 июня 2003 г.

Сайт автора: http://tgolden.sc.sabren.com/index.html.

Модуль лицензируется согласно GPL-совместимой лицензии MIT: http://www.opensource.org/licenses/mit-license.php.

Пример

import wmi

c = wmi.WMI ()
for s in c.Win32_Service ():
    if s.State == 'Stopped':
        print s.Caption, s.State 

Загрузка

Вы можете скачать модуль со странички автора: http://tgolden.sc.sabren.com/python/wmi.html. Там же вы найдёте историю версий (в т.ч. самую свежую версию из репозитория) и документацию на английском языке, а также некоторые замечания относительно использования этого модуля в службах Windows и при многопоточном программировании в Python. Кроме того, вы можете скачать модуль и прямо здесь:

wmi-1.3.1.zip (26 699 байт)

Модуль wmi, инсталлятор, readme и документация на английском языке. Версия 1.3.1 от 5 июня 2007 г.
Внимание! Возможно, на сайте автора вы сможете найти более свежую версию.

Установка

Распакуйте скачанный архив в удобное вам место и выполните команду наподобие следующей:

python setup.py install 

Введение в использование модуля

О том, что из себя в принципе представляет WMI, вы можете прочитать здесь: Введение в Windows Management Instrumentation (WMI).

Дальнейшее изложение использует язык программирования Python и предполагает, что вы загрузили и установили сам Python, необходимые расширения pywin32 и описываемый здесь WMI модуль для Python. Python может использовать WMI посредством пакетов, поддерживающих COM, например, Win32 Extensions от Марка Хаммонда (Mark Hammond) или comtypes от Томаса Хеллера (Thomas Heller). Данный WMI модуль предполагает, что необходимые расширения pywin32 присутствуют, и предоставляет немного более благоприятный интерфейс для Python, чем иногда "грязный" скриптовый API WMI. (Примечание переводчика: для работы данного модуля вполне достаточно стандартной установки ActivePython.) Примечание: этот модуль - только обёртка для функциональных возможностей pywin32, и если WMI под pywin32 кажется вам слишком медленным, этот модуль не будет работать быстрее.

Здесь не будет рассматриваться то, что вы можете сделать с WMI вообще, за исключением демонстрации небольшого количества функциональных возможностей в пределах описания модуля. В Интернете можно найти немало примеров работы с WMI (и вы сможете использовать большинство возможностей WMI, если будете пробовать достаточно целеустремлённо).

Подключение

В большинстве случаев вы просто подключаетесь к локальной машине со значениями по умолчанию:

import wmi
c = wmi.WMI() 

Если вы подключаетесь к другой машине, определите её имя как первый параметр:

import wmi
c = wmi.WMI("other_machine") 

Выполнение запросов

Самая обычная вещь, которую вы будете делать с WMI - это получать информацию о различных частях вашей системы. Вы определяете, какой класс WMI опросить, и затем обращаетесь к нужному атрибуту WMI-объекта Python:

import wmi
c = wmi.WMI()
for os in c.Win32_OperatingSystem():
    print os.Caption 

"Какой WMI класс опросить", как было упомянуто выше - это далеко не всегда такой уж простой вопрос, как бы просто это не звучало. Однако, используя хороший поисковый сервер, вы можете быть в значительной степени уверены, что кто-нибудь где-нибудь уже сделал ту самую работу, которая вам нужна, хотя бы и на другом языке программирования.

Обратите внимание, что хотя как правило есть только одна операционная система, запрос к WMI всегда возвращает список, состоящий, возможно, из одного элемента. Элементы списка обёрнуты модулем Python для доступа к атрибутам. В данном случае класс Win32_OperatingSystem имеет несколько атрибутов, один из которых - Caption, который возвращает имя установленной операционной системы.

Мониторинг

WMI имеет концепцию событий. Есть два типа событий - встроенные и внешние, которые описаны ниже. Модуль Python делает различие между ними настолько прозрачным, насколько это возможно. Например, вы хотите отследить запуск новых процессов:

import wmi
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for("creation")
while True:
    new_process = process_watcher()
    print new_process.Caption 

v1.3.1. Если вы не определяете тип встроенного события, будет принято событие "operation", которое вызывается при любом изменении объекта этого класса.

Обновление

Некоторые (но ни в коем случае не все) классы WMI предоставляют возможность записи информации. Вы можете это проделать, устанавливая атрибуты как обычно в Python. Обратите внимание, что класс может позволить вам сделать это без выдачи каких-либо ошибок даже при том, что ничего полезного не произойдёт. Чтобы изменить отображаемое имя службы, например, вы должны вызвать метод Change. Вы можете без ошибки обновить атрибут displayName непосредственно, но это не будет иметь никакого эффекта.

Самый типичный случай, когда вы можете установить атрибут непосредственно - когда вы создаете абсолютно новый объект класса методом new. В том случае вы можете или установить все параметры как параметры вызова new, или определить их один за другим впоследствии.

Методы

Некоторые классы WMI имеют методы для оперирования с ними. Вы можете вызывать их, как если бы они были обычными классами или методами объектов в Python. Начиная с версии 1.3.1, могут быть установлены параметры; они должны быть именованными. Например, если вы хотите остановить службу RunAs ("seclogon", вторичный вход в систему), вы можете написать:

import wmi
c = wmi.WMI()
for service in c.Win32_Service(Name="seclogon"):
    result, = service.StopService()
    if result == 0:
        print "Service", service.Name, "stopped"
    else:
        print "Some problem"
    break
else:
    print "Service not found" 

Дополнительный материал

Основы того, что может быть сделано модулем WMI, описаны выше, и это вероятно то, что нужно большинству людей. Однако в WMI есть много небольших тонкостей, и изучая какой-нибудь VBS-ориентированный пример где-нибудь в Интернете, вы можете раздумывать: "И как же я сделаю это в Python?".

Расширенное подключение

Функция connect (названная в нашем модуле как WMI) имеет довольно много параметров, большинство которых являются необязательными и могут безопасно игнорироваться. Большинство из их можно увидеть в документации Microsoft по WMI-моникерам http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_arib.mspx. Мы же опишем здесь только некоторые из них.

Подключение к удалённому компьютеру

Это самый обычный и наиболее простой необязательный параметр. Это - первый позиционный параметр или параметр "computer". Вы можете подключиться к вашему собственному компьютеру, не задавая ничего, пустую строку, точку или имя компьютера любым способом, включая "localhost". Но обычно достаточно не передавать параметр вообще. Чтобы подключиться к подсистеме WMI на компьютере с именем "MachineB", можно написать:

import wmi
c = wmi.WMI("MachineB") 

Подключение к удалённому компьютеру под указанным пользователем

Это - вторая самая обычная потребность, которая работает довольно просто, но с несколькими нюансами. Первый нюанс - это то, что независимо от того, насколько хитро вы попробуете всё запутать - вы не сможете подключиться к вашему собственному компьютеру этим путём. Второй - эта методика не всегда хорошо сочетается со многими уровнями безопасности WMI. Чтобы подключиться к машине с именем "MachineB" под именем пользователя "fred" с паролем "secret", можно написать:

import wmi
c = wmi.WMI("MachineB", user=r"MachineB\fred", password="secret") 

Подключение к указанному пространству имён

WMI классы организованы в иерархию пространств имён. Большинство полезных классов находится в пространстве имён cimv2, которое, как правило, является значением по умолчанию. Но дополнительные провайдеры WMI могут определять особые пространства имён, например MicrosoftIISv2 или DEFAULT/StdRegProv. Чтобы использовать пространство имён, отличное от значения по умолчанию (которое, кстати, может оказаться совсем не тем, что вам нужно!) определите параметр "namespace". Все пространства имён начинаются с root, что не обязательно указывать, хотя, если вы хотите непосредственно определить пространство имён root, вы можете это сделать.

import wmi
c = wmi.WMI(namespace="WMI") 

Указание полного моникера

В некоторых случаях вы захотите указать полный моникер, например потому, что этот моникер довольно сложен, или потому, что вы хотите его "вырезать и вставлять" каким бы то ни было способом. В том случае передайте моникер как строку через параметр "moniker":

import wmi
c = wmi.WMI(moniker="winmgmts:{impersonationLevel=impersonate,(LockMemory, !IncreaseQuota)}") 

Подключение к указанному классу или объекту

Особый случай полного моникера - это использование моникера, чтобы соединиться непосредственно с WMI классом или даже определенным объектом. Модуль обратит внимание, что моникер обращается к классу или объекту, и возвратит объект непосредственно, а не пространство имён. Любой путь объекта WMI может использоваться как моникер, чтобы восстановить его, например вот так можно подсоединиться непосредственно к классу Win32_LogicalDisk:

import wmi
logical_disk = wmi.WMI(moniker="//./root/cimv2:Win32_LogicalDisk") 

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

import wmi
c_drive = wmi.WMI(moniker='//./root/cimv2:Win32_LogicalDisk.DeviceID="C:"') 

Это тот же самый объект, который вы получили бы, запрашивая Win32_LogicalDisk в пространстве имён cimv2 с параметром DeviceID = "C:", поэтому с точки зрения модуля это не слишком полезно. Однако, это довольно обычное использование в примерах на VBS в Интернете, и немного упрощает перевод.

Фильтрация возвращаемого списка

Когда Вы "вызываете" WMI класс, вы можете указать простое равенство для параметра, чтобы сузить список. Эта фильтрация обрабатывается на уровне WMI; вы можете делать любую последующую фильтрацию, которая вам нужна, в коде Python, как только вы получите значения. Обратите внимание, что даже если список содержит только один элемент, это всё еще список. Чтобы найти все жёсткие диски, можно написать:

import wmi
c = wmi.WMI()
for disk in c.Win32_LogicalDisk(DriveType=3):
    print disk.Name 

Выбор только указанных полей

По умолчанию в запросе будут возвращены все поля в классе. Из соображений производительности или просто управляемости, вы можете получать только некоторые поля. Это можно сделать, устанавливая первый позиционный параметр как список имён полей. Обратите внимание, что ключевое поле (обычно идентификатор, уникальное имя или даже их комбинация) будет возвращаться всегда:

import wmi
c = wmi.WMI()
for disk in c.Win32_LogicalDisk(["Caption", "Description"], DriveType=3):
    print disk.Caption, disk.Description 

Исполнение произвольных запросов WQL

Если вы хотите выполнить произвольные запросы WMI, используя псевдо-SQL язык WQL, вы можете использовать метод query пространства имён. Например, перечисление всех нежёстких дисков:

import wmi
c = wmi.WMI()
wql = "SELECT Caption, Description FROM Win32_LogicalDisk WHERE DriveType <> 3"
for disk in c.query(wql):
    print disk.Caption, disk.Description 

Внутренние события

Внутренние события происходят, когда вы подключаетесь к общему механизму событий, предлагаемому системой WMI, чтобы опросить другие классы от вашего имени. Вы можете проследить создание, модификацию или удаление любого WMI класса. Вы должны определить тип события (создание, удаление или модификация) и задать частоту опроса в целых секундах. После этих параметров вы можете привести именованные параметры, чтобы обычным способом уменьшить количество возвращённых событий. Обратите внимание, что, так как это опрашивает неявно, вы не можете использовать это для, например, контроля полной структуры каталога.

Чтобы наблюдать за системным логом ошибок, напишите:

# -*- coding: cp1251 -*-
import wmi
c = wmi.WMI(privileges=["Security"])
watcher = c.Win32_NTLogEvent.watch_for("creation", 2, Type="error")
while 1:
    error = watcher()
    print "Ошибка в логе %s: %s" % (error.Logfile, error.Message)
    # посылка письма администратору и т.п. 

Один нюанс: опрос происходит с той частотой, с какой вы определили. Таким образом, возможно пропустить какие-то события.

v1.3.1: метод watch_for возвращает фактически специальный объект события wmi, который включает объект, который вызвал код и, для внутренних событий, тип события, отметку времени и предыдущее значение при модификации.

Внешние события

Обратите внимание, что несмотря на то, что "Win32_NTLogEvent" заканчивается на "Event", на самом деле это - не внешнее событие. Вы можете определить, какие классы являются внешними событиями, исследуя их происхождение:

import wmi
c = wmi.WMI()
print c.Win32_PowerManagementEvent.derivation() 

Или вы можете идти от вершины вниз и разыскивать подклассы __ExtrinsicEvent:

import wmi
c = wmi.WMI()
for i in c.subclasses_of("__ExtrinsicEvent"):
    print i 

Внешние события используются аналогичным способом, как внутренние. Различие состоит в том, что любой тип события и задержка игнорируются, т.к. WMI не опрашивает от вашего имени, а ожидает на основной подсистеме. Метод watch_for возвращает все ещё объект события wmi (v1.3.1), но уже без event_info, который не поддерживается WMI. Предположим, вы хотите делать что-то всякий раз, когда ваш компьютер выходит из режима standby, например, уведомить группу IM о вашем присутствии:

# -*- coding: cp1251 -*-
import wmi
import datetime
c = wmi.WMI()
watcher = c.Win32_PowerManagementEvent.watch_for(EventType=7)
while True:
    event = watcher()
    print "resumed"
    # Число 100-наносекундных интервалов с 1-ого января 1601!
    # TIME_CREATED, возможно, не поддерживается в Win2K
    # прим. перев.: время будет выведено без учёта поясов и летнего времени (т.е. "чистое" GMT).
    if hasattr(event, "TIME_CREATED"):
        ns100 = int(event.TIME_CREATED)
        offset = datetime.timedelta(microseconds=ns100 / 10)
        base = datetime.datetime(1601, 1, 1)
        print "Resumed at", base  + offset 

Для внутреннего события модификации вы можете произвести сравнение значений "до" и "после" объекта "триггера":

import wmi
c = wmi.WMI()
watcher = c.Win32_Process.watch_for("modification")
event = watcher()
print "Modification occurred at", event.timestamp

print event.path()
prev = event.previous
curr = event
for p in prev.properties:
    pprev = getattr(prev, p)
    pcurr = getattr(curr, p)
    if pprev != pcurr:
        print p
        print "  Previous:", pprev
        print "   Current:", pcurr 

Слежение с тайм-аутами

Возможно и большее! Хотя вы можете использовать слежение в потоках, в некоторых случаях проще осуществлять опрос через некоторые интервалы времени. Если, например, вы хотите контролировать события печати на двух компьютерах, не занимаясь потоками и очередями, вы можете написать:

import wmi

def wmi_connection(server, username, password):
    print "attempting connection with", server
    if username:
        return wmi.WMI(server, user=username, password=password)
    else:
        return wmi.WMI(server)

servers = [
   (".", "", ""),
   ("goyle", "wmiuser", "secret")
]
watchers = {}
for server, username, password in servers:
    connection = wmi_connection(server, username, password)
    watchers[server] = connection.Win32_PrintJob.watch_for("creation")

while True:
    for server, watcher in watchers.items():
        try:
            event = watcher(timeout_ms=10)
        except wmi.x_wmi_timed_out:
            pass
        else:
            print "print job added on", server
            print event.Name
            print event.TotalPages, event.PagesPrinted, event.Owner 

Исследование доступных методов

Если вы исследуете ключи словаря methods, в котором каждый обёрнутый класс WMI кэширует свои обёрнутые методы, вы увидите, какие методы поддерживаются:

import wmi
c = wmi.WMI()
c.Win32_ComputerSystem.methods.keys() 

Вывод сигнатур методов

Каждый обёрнутый метод имеет сигнатуру. Если функция (типа Shutdown) требует дополнительных привилегий, это также будет обозначено:

import wmi
c = wmi.WMI()
os = c.Win32_OperatingSystem
for method_name in os.methods:
    method = getattr(os, method_name)
    print method 

Обратите внимание, что если параметр, как ожидается, будет списком, это будет отображено со скобками "[]". Обратите внимание также, что возвращаемые значения - всегда словарь, хотя бы и имеющий длину, равную единице.

Поиск эквивалентов методов Win32 API

Немного удивительно, но WMI может сообщить вам, какой вызов Win32 API происходит, когда вы вызываете метод WMI (но, к сожалению, не свойство). Это поддерживается как атрибут provenance обёртки функции:

import wmi
c = wmi.WMI()
print c.Win32_Process.Create.provenance 

Создание объектов WMI

WMI предоставляет метод SpawnInstance_, который обёрнут как метод new класса WMI в Python. Но вы будете использовать этот метод намного менее часто, чем вы, возможно, думаете. Например, если вы хотите создать новый дисковый ресурс, вместо того чтобы использовать Win32_Share.new, вы фактически вызовете метод Create класса Win32_Share. Фактически, большинство классов, которые позволяют создание объекта через WMI, предлагают метод Create (Win32_Process, Win32_Share и т.д.).

import wmi
c = wmi.WMI()
result, = c.Win32_Share.Create(Path="c:\\temp", Name="temp", Type=0)
if result == 0:
    print "Share created successfully"
else:
    raise RuntimeError, "Problem creating share: %d" % result 

Иногда вы будете должны породить новый объект - например, если вы должны подать объект WMI, созданный на лету, другому объекту. Типичный пример - это передача описателя безопасности новому объекту или обработка информации запуска для нового процесса. Пример из MSDN http://msdn2.microsoft.com/en-us/library/aa394375.aspx может быть переведён на Python следующим образом:

# -*- coding: cp1251 -*-
import win32con
import wmi

c = wmi.WMI()
process_startup = c.Win32_ProcessStartup.new()
process_startup.ShowWindow = win32con.SW_NORMAL
# можно было также:
# process_startup = c.Win32_ProcessStartup.new(ShowWindow=win32con.SW_NORMAL)

process_id, result = c.Win32_Process.Create(
    CommandLine="notepad.exe",
    ProcessStartupInformation=process_startup
)
if result == 0:
    print unicode("Процесс запущен успешно: %d" % process_id, "cp1251")
else:
    raise RuntimeError, \
        unicode("Неудачный запуск процесса: %d" % result, "cp1251") 

Информация о классе/объекте

Каждый класс или объект возвращают читабельную версию своей структуры, если представлены как строка:

import wmi
c = wmi.WMI()
print c.Win32_OperatingSystem
for os in c.Win32_OperatingSystem():
    print os 

Иерархия объекта

Объекты WMI существуют в пределах иерархии классов. Каждый объект знает своих собственных предков:

import wmi
c = wmi.WMI()
print c.Win32_Process.derivation() 

Вы можете также просматривать дерево вниз, находя все подклассы названного класса, произвольно фильтруя информацию с помощью регулярных выражений. Поиск всех классов внешних событий (не обозначенных начальным символом подчеркивания):

import wmi
c = wmi.WMI()
for extrinsic_event in c.subclasses_of("__ExtrinsicEvent", "[^_].*"):
    print extrinsic_event
    print "  ", " < ".join(getattr(c, extrinsic_event).derivation()) 

Сравнение двух объектов WMI на равенство

Оператор __eq__ перегружен в обёрнутых классах WMI и вызывает метод CompareTo, сравнивая два объекта WMI на равенство.

Связанные классы

Associators - это классы, которые связывают вместе другие классы. Если, например, вы хотите знать, какие группы есть в вашей системе, и какие пользователи находятся в каждой группе:

import wmi
c = wmi.WMI()

for group in c.Win32_Group():
    print group.Caption
    for user in group.associators(wmi_result_class="Win32_UserAccount"):
        print "  ", user.Caption 

Это может быть записано также в терминах классов associator:

import wmi
c = wmi.WMI()

for group in c.Win32_Group():
    print group.Caption
    for user in group.associators("Win32_GroupUser"):
        print "  ", user.Caption 

Повышение производительности

Благодаря полезному сотрудничеству с Паулем Тиманном (Paul Tiemann), модуль значительно повысил свою производительность при помощи комбинации кэширования и лёгких запросов, где это необходимо. Здесь описано не всё, а только наиболее явные усовершенствования, удаляющие интроспекцию во время выполнения и кэширующие так, чтобы все обёртки были сгенерированы только по требованию и могли предкэшироваться.

Исключение интроспекции

Ядро модуля и большая его используемая часть находятся в интерпретаторе. По этой причине, когда вы обращаетесь к пространству имён WMI, разыскиваются все классы, доступные в этом пространстве имён. Это может занимать продолжительное время на большом пространстве имён, да и не нужно даже на меньших пространствах имён, если вы знаете точно, к чему вы будете обращаться после. Поэтому в "промышленном" коде вы можете это отключить:

import wmi
c = wmi.WMI(find_classes=False) 

Если вы определили, какие классы являются доступными, вы всё ещё можете использовать subclasses_of (как описано выше), чтобы искать, например, классы производительности, доступные на данной машине во время выполнения:

import wmi
c = wmi.WMI(find_classes=False)
perf_classes = c.subclasses_of("Win32_PerfRawData") 

Предкэширование обёрток классов и методов

Чтобы избегать начального запуска поиска, когда к классу делается запрос или вызывается его метод, можно просто заранее поместить класс в кэш, обращаясь к нему. Развивая код, приведённый выше:

# -*- coding: cp1251 -*-
import wmi
c = wmi.WMI(find_classes=False)
for perf_class in c.subclasses_of("Win32_PerfRawData"):
    # не делать ничего, только получить это в кэш
    getattr(c, perf_class) 

Указание полей в запросе

По умолчанию запрос WMI возвратит все поля класса для каждого объекта. Определяя поля, вы задаёте их как первый параметр запроса, во избежание любых ресурсоёмких поисков:

import wmi
c = wmi.WMI(find_classes=False)
for i in c.Win32_Process(["Caption", "ProcessID"]):
    print i 

Безопасность

Самый простой путь, чтобы обратиться к функциональным возможностям WMI, состоит в том, чтобы исполнять скрипт с правами администратора домена. Другие методы конечно возможны, но таят в себе различные подводные камни.

Безопасность NT

Пользователь должен иметь некоторый доступ к машине, функциональные возможности WMI которой вызываются. Это может заключаться во включении его в локальную группу администраторов или в определении доступа конкретному пользователю.

Безопасность DCOM

WMI - технология, основанная на DCOM. Если есть проблема подтверждения подлинности на уровне DCOM, тогда, в теории, вы должны иметь ту же самую проблему, делая DispatchEx на Word.Application. Программа, которую вам стоит посмотреть - dcomcnfg.exe.

Безопасность WMI

Пространства имён WMI - это системные объекты со своими собственными дескрипторами безопасности. Если Вы обратитесь к MMC-оснастке WMI через mmc.exe, вы найдёте там вкладку безопасности. Учетная запись, использующая функциональные возможности WMI на этой машине, должна иметь достаточный доступ.

WMI и потоки

WMI - это механизм, основанный на COM/DCOM, поэтому механизм потоков COM также используется и в WMI. Это не зависит от того, действительно ли ваша программа явно вызывает поток в Python: например, если вы выполняете код в службе, вы вероятно используете потоки, нравится вам это или нет. Пример с потоками на Python:

import pythoncom
import wmi
import threading
import time

class Info(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        print 'In Another Thread...'
        pythoncom.CoInitialize()
        try:
            c = wmi.WMI()
            for i in range(5):
                for process in c.Win32_Process():
                    print process.ProcessId, process.Name
                time.sleep(2)
        finally:
            pythoncom.CoUninitialize()

if __name__ == '__main__':
    print 'In Main Thread'
    c = wmi.WMI()
    for process in c.Win32_Process():
        print process.ProcessId, process.Name
    Info().start() 

Перейти на главную страничку сайта (список статей, файлы для скачивания)

© 2007 http://www.script-coding.com При любом использовании материалов сайта обязательна ссылка на него как на источник информации, а также сохранение целостности и авторства материалов.

 
MyTetra Share v.0.52
Яндекс индекс цитирования