使用Python玩转WMI
admin
2023-07-31 00:46:50
0

最近在网上搜索Python和WMI相关资料时,发现大部分文章都千篇一律,并且基本上只说了很基础的使用,并未深入说明如何使用WMI。本文打算更进一步,让我们使用Python玩转WMI。

1 什么是WMI

具体请看微软官网对WMI的介绍。这里简单说明下,WMI的全称是Windows Management Instrumentation,即Windows管理规范。它是Windows操作系统上管理数据和操作的基础设施。我们可以使用WMI脚本或者应用自动化管理任务等。

从Using WMI可以知道WMI支持如下语言:

Application language Topic
Scripts written in Microsoft ActiveX script hosting, including Visual Basic Scripting Edition (VBScript) and Perl Scripting API for WMI.

Start with Creating a WMI Script.

For script code examples, see WMI Tasks for Scripts and Applications and the TechNet ScriptCenter Script Repository.

Windows PowerShell Getting Started with Windows PowerShell

WMI PowerShell Cmdlets, such as Get-WmiObject.

Visual Basic applications Scripting API for WMI.
Active Server Pages Scripting API for WMI.

Start with Creating Active Server Pages for WMI.

C++ applications COM API for WMI.

Start with Creating a WMI Application Using C++ and WMI C++ Application Examples (contains examples).

.NET Framework applications written in C#, Visual Basic .NET, or J# Classes in the Microsoft.Management.Infrastructure namespace. (The System.Management namespace is no longer supported). For more information, see WMI .NET Overview.

很遗憾,WMI并不原生支持Python。不过没有关系,它支持VB,而Python中的两个第三方库wmi和win32com,均能以类似VB的用法来使用。那么接下来,我们来讲讲如何使用。

 

2 使用WMI

2.1 使用wmi库操作WMI

以下是一个遍历所有进程,所有服务的示例:

123456789 import wmic = wmi.WMI ()# 遍历进程for process in c.Win32_Process ():    print process.ProcessId, process.Name # 遍历服务for service in c.Win32_Service ():    print service.ProcessId, service.Name

可以看到,使用起来非常简单。但是有两个问题:一是wmi库实在是太慢了,能不能快点?二是如何知道例子中process和service有哪些属性(比如ProcessId等)?由于wmi库是动态生成底层执行语句,用dir(process)这种方式是获取不到ProcessId这种属性的。

针对第一个问题,我们可以使用win32com这个库来解决,它相较于wmi的速度快了很多。而第二个问题,先卖个关子,后文会有介绍。

2.2 使用win32com库操作WMI

win32com能模仿VB的行为,想了解如何使用win32com来操作WMI,最直接的方式是了解如何使用VB来操作WMI。在微软的官网上提供了很多现成的例子:WMI Tasks: Processes, WMI Tasks: Services。

其中一个例子关于进程是这样的:

12345678910111213 strComputer = \”.\”Set objWMIService = GetObject(\”winmgmts:\” & \”{impersonationLevel=impersonate}!\\\\\” & strComputer & \”\\root\\cimv2\”)Set colProcesses = objWMIService.ExecQuery(\”Select * from Win32_Process\”)For Each objProcess in colProcesses     Wscript.Echo \”Process: \” & objProcess.Name    sngProcessTime = (CSng(objProcess.KernelModeTime) + CSng(objProcess.UserModeTime)) / 10000000    Wscript.Echo \”Processor Time: \” & sngProcessTime    Wscript.Echo \”Process ID: \” & objProcess.ProcessID    Wscript.Echo \”Working Set Size: \” & objProcess.WorkingSetSize    Wscript.Echo \”Page File Size: \” & objProcess.PageFileUsage    Wscript.Echo \”Page Faults: \” & objProcess.PageFaultsNext

它做了这样一件事:首先通过GetObject连接到Win32_Process所在的名称空间,然后执行WQL语句(类似SQL的查询语句)查到所有的进程,再把每一个进程的相关信息打印出来。WQL的具体用法请见官网,这里不详细介绍。

那么用win32com就可以这么写(例子中打印的属性为了简便,就不像上面那么多啦):

1234567 from win32com.client import GetObject wmi = GetObject(\’winmgmts:/root/cimv2\’)# wmi = GetObject(\’winmgmts:\’) #更简单的写法processes = wmi.ExecQuery(\’Select * from Win32_Process\’)for process in processes:    print(process.ProcessID, process.Name)

看上去,VB和win32com的用法非常接近!那么当我们想要使用win32com对WMI进行操作时,就可以参考微软官网上VB的例子,然后比葫芦画瓢写出Python版的代码。

上例中,我们使用了查询函数ExecQuery来查询符合条件的内容,不过如果我们仅仅是想要获得所有的数据,而没有特定的限定条件,就可以使用更简单的方式——InstancesOf,那么就可以写成下面这样:

123456 from win32com.client import GetObject wmi = GetObject(\’winmgmts:/root/cimv2\’)processes = wmi.InstancesOf(\’Win32_Process\’)for process in processes:    print(process.ProcessID, process.Name)

有读者可能会问,我们怎么知道自己想要了解的内容在哪个名称空间,我们应该获取哪个实例,又该获取实例中的哪些属性呢?

 

3 WMI的名称空间

使用下面的脚本可以获得当前计算机上的名称空间:

namespaces = wmi.InstancesOf(\’__Namespace\’)
for namespace in namespaces:
enum_namespace(\'{name}/{subname}\’.format(name=name,
subname=namespace.Name))
except pywintypes.com_error:
print(name, \’limit of authority\’)
else:
print(name)
enum_namespace(\’root\’)

我们使用Python玩转WMI。

1 什么是WMI

具体请看微软官网对WMI的介绍。这里简单说明下,WMI的全称是Windows Management Instrumentation,即Windows管理规范。它是Windows操作系统上管理数据和操作的基础设施。我们可以使用WMI脚本或者应用自动化管理任务等。

从Using WMI可以知道WMI支持如下语言:

Application language Topic
Scripts written in Microsoft ActiveX script hosting, including Visual Basic Scripting Edition (VBScript) and Perl Scripting API for WMI.

Start with Creating a WMI Script.

For script code examples, see WMI Tasks for Scripts and Applications and the TechNet ScriptCenter Script Repository.

Windows PowerShell Getting Started with Windows PowerShell

WMI PowerShell Cmdlets, such as Get-WmiObject.

Visual Basic applications Scripting API for WMI.
Active Server Pages Scripting API for WMI.

Start with Creating Active Server Pages for WMI.

C++ applications COM API for WMI.

Start with Creating a WMI Application Using C++ and WMI C++ Application Examples (contains examples).

.NET Framework applications written in C#, Visual Basic .NET, or J# Classes in the Microsoft.Management.Infrastructure namespace. (The System.Management namespace is no longer supported). For more information, see WMI .NET Overview.

很遗憾,WMI并不原生支持Python。不过没有关系,它支持VB,而Python中的两个第三方库wmi和win32com,均能以类似VB的用法来使用。那么接下来,我们来讲讲如何使用。

 

2 使用WMI

2.1 使用wmi库操作WMI

以下是一个遍历所有进程,所有服务的示例:

123456789 import wmic = wmi.WMI ()# 遍历进程for process in c.Win32_Process ():    print process.ProcessId, process.Name # 遍历服务for service in c.Win32_Service ():    print service.ProcessId, service.Name

可以看到,使用起来非常简单。但是有两个问题:一是wmi库实在是太慢了,能不能快点?二是如何知道例子中process和service有哪些属性(比如ProcessId等)?由于wmi库是动态生成底层执行语句,用dir(process)这种方式是获取不到ProcessId这种属性的。

针对第一个问题,我们可以使用win32com这个库来解决,它相较于wmi的速度快了很多。而第二个问题,先卖个关子,后文会有介绍。

2.2 使用win32com库操作WMI

win32com能模仿VB的行为,想了解如何使用win32com来操作WMI,最直接的方式是了解如何使用VB来操作WMI。在微软的官网上提供了很多现成的例子:WMI Tasks: Processes, WMI Tasks: Services。

其中一个例子关于进程是这样的:

12345678910111213 strComputer = \”.\”Set objWMIService = GetObject(\”winmgmts:\” & \”{impersonationLevel=impersonate}!\\\\\” & strComputer & \”\\root\\cimv2\”)Set colProcesses = objWMIService.ExecQuery(\”Select * from Win32_Process\”)For Each objProcess in colProcesses     Wscript.Echo \”Process: \” & objProcess.Name    sngProcessTime = (CSng(objProcess.KernelModeTime) + CSng(objProcess.UserModeTime)) / 10000000    Wscript.Echo \”Processor Time: \” & sngProcessTime    Wscript.Echo \”Process ID: \” & objProcess.ProcessID    Wscript.Echo \”Working Set Size: \” & objProcess.WorkingSetSize    Wscript.Echo \”Page File Size: \” & objProcess.PageFileUsage    Wscript.Echo \”Page Faults: \” & objProcess.PageFaultsNext

它做了这样一件事:首先通过GetObject连接到Win32_Process所在的名称空间,然后执行WQL语句(类似SQL的查询语句)查到所有的进程,再把每一个进程的相关信息打印出来。WQL的具体用法请见官网,这里不详细介绍。

那么用win32com就可以这么写(例子中打印的属性为了简便,就不像上面那么多啦):

1234567 from win32com.client import GetObject wmi = GetObject(\’winmgmts:/root/cimv2\’)# wmi = GetObject(\’winmgmts:\’) #更简单的写法processes = wmi.ExecQuery(\’Select * from Win32_Process\’)for process in processes:    print(process.ProcessID, process.Name)

看上去,VB和win32com的用法非常接近!那么当我们想要使用win32com对WMI进行操作时,就可以参考微软官网上VB的例子,然后比葫芦画瓢写出Python版的代码。

上例中,我们使用了查询函数ExecQuery来查询符合条件的内容,不过如果我们仅仅是想要获得所有的数据,而没有特定的限定条件,就可以使用更简单的方式——InstancesOf,那么就可以写成下面这样:

123456 from win32com.client import GetObject wmi = GetObject(\’winmgmts:/root/cimv2\’)processes = wmi.InstancesOf(\’Win32_Process\’)for process in processes:    print(process.ProcessID, process.Name)

有读者可能会问,我们怎么知道自己想要了解的内容在哪个名称空间,我们应该获取哪个实例,又该获取实例中的哪些属性呢?

 

3 WMI的名称空间

使用下面的脚本可以获得当前计算机上的名称空间:

s=\”crayon-title\”>

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...