最近在开发一个应用需要实时监控进程的运行情况,用Python开发类似windows特定的应用时,当然首选pywin32, 可是用win32process模块来遍历当前系统所有进程时,可能会因为权限的问题,pywin会抛出异常,感觉开发起来不大顺畅, 但如果采用WMI模块,问题则可以变得轻松许多,两句代码即可搞定。

先看看用win32process如何来遍历:

 1 import os
 2 import win32process, win32security, win32api, win32con
 3 
 4 #获取所有的pid
 5 pidList = win32process.EnumProcesses()
 6 
 7 for pid in pidList:
 8 
 9     try:
10         # system idle process may raise exception
11         # pid 为 0、4等 的进程会抛出异常
12         procHandle = win32api.OpenProcess(win32con.PROCESS_VM_OPERATION
13             |win32con.PROCESS_VM_READ
14             |win32con.PROCESS_VM_WRITE
15             |win32con.PROCESS_QUERY_INFORMATION, 0, pid)
16 
17         try:
18             # Processes run as system may raise exception
19             # 系统级别的进程会抛出异常,不得不忽略掉
20             modHandles = win32process.EnumProcessModules(procHandle)
21             
22             # Get exe Path
23             procPath = win32process.GetModuleFileNameEx(procHandle, modHandles[0])
24             baseName = os.path.basename(procPath)
25             print procPath
26             
27         except Exception, e1:
28             print str(pid) + ": " + str(e1)
29         finally:
30             win32api.CloseHandle(procHandle)
31             
32     except Exception, e:
33         print str(pid) + ": " + str(e)

做了一长串动作,还不能得到所有的进程运行情况,下面该wmi上场了:

先是简单的import,然后获取wmi的一个实例,接下来就可以遍历了, 如下:

1 import wmi
2 c = wmi.WMI()
3 for process in c.Win32_Process():
4     print str(process)

win32process的详细属情如下(python可以不关心类型):

class Win32_Process : CIM_Process
{
    string Caption;
    string CommandLine;
    string CreationClassName;
    datetime CreationDate;
    string CSCreationClassName;
    string CSName;
    string Description;
    string ExecutablePath;
    uint16 ExecutionState;
    string Handle;
    uint32 HandleCount;
    datetime InstallDate;
    uint64 KernelModeTime;
    uint32 MaximumWorkingSetSize;
    uint32 MinimumWorkingSetSize;
    string Name;
    string OSCreationClassName;
    string OSName;
    uint64 OtherOperationCount;
    uint64 OtherTransferCount;
    uint32 PageFaults;
    uint32 PageFileUsage;
    uint32 ParentProcessId;
    uint32 PeakPageFileUsage;
    uint64 PeakVirtualSize;
    uint32 PeakWorkingSetSize;
    uint32 Priority;
    uint64 PrivatePageCount;
    uint32 ProcessId;
    uint32 QuotaNonPagedPoolUsage;
    uint32 QuotaPagedPoolUsage;
    uint32 QuotaPeakNonPagedPoolUsage;
    uint32 QuotaPeakPagedPoolUsage;
    uint64 ReadOperationCount;
    uint64 ReadTransferCount;
    uint32 SessionId;
    string Status;
    datetime TerminationDate;
    uint32 ThreadCount;
    uint64 UserModeTime;
    uint64 VirtualSize;
    string WindowsVersion;
    uint64 WorkingSetSize;
    uint64 WriteOperationCount;
    uint64 WriteTransferCount;

  };

 

当然,你还可以通过指定参数来找到特定的进程:

 

1 >>> import wmi
2 >>> c = wmi.WMI()
3 >>> for process in c.Win32_Process(name="ugraf.exe"):
4 ...  print str(process)
5 ...  

 

以上代码会得到如下结果:

 1 instance of Win32_Process
 2 {
 3  Caption = "ugraf.exe";
 4  CommandLine = "\"C:\\UGS\\nx75\\UGII\\ugraf.exe\" ";
 5  CreationClassName = "Win32_Process";
 6  CreationDate = "20120409132415.275816+480";
 7  CSCreationClassName = "Win32_ComputerSystem";
 8  CSName = "Think-pad-LT";
 9  Description = "ugraf.exe";
10  ExecutablePath = "C:\\UGS\\nx75\\UGII\\ugraf.exe";
11  Handle = "3000";
12  HandleCount = 489;
13  KernelModeTime = "140468750";
14  MaximumWorkingSetSize = 1413120;
15  MinimumWorkingSetSize = 204800;
16  Name = "ugraf.exe";
17  OSCreationClassName = "Win32_OperatingSystem";
18  OSName = "Microsoft Windows XP Professional|C:\\WINDOWS|\\Device\\Harddisk0\\Partition2";
19  OtherOperationCount = "10980";
20  OtherTransferCount = "2345931";
21  PageFaults = 125955;
22  PageFileUsage = 346304512;
23  ParentProcessId = 4280;
24  PeakPageFileUsage = 346570752;
25  PeakVirtualSize = "568078336";
26  PeakWorkingSetSize = 391847936;
27  Priority = 8;
28  PrivatePageCount = "346304512";
29  ProcessId = 3000;
30  QuotaNonPagedPoolUsage = 45816;
31  QuotaPagedPoolUsage = 908324;
32  QuotaPeakNonPagedPoolUsage = 46520;
33  QuotaPeakPagedPoolUsage = 930572;
34  ReadOperationCount = "1613";
35  ReadTransferCount = "15446521";
36  SessionId = 0;
37  ThreadCount = 8;
38  UserModeTime = "173281250";
39  VirtualSize = "556150784";
40  WindowsVersion = "5.1.2600";
41  WorkingSetSize = "86568960";
42  WriteOperationCount = "1196";
43  WriteTransferCount = "262987";
44 };

 

顺便提一下安装,pywin32是不带这个模块的,需要另外安装,可以通过后面给出的链接下载,然后运行 python setup.py install安装,我是直接把wmi.py丢到python安装目录下的 lib 文件夹下, 即可通过 import wmi 导入该模块。

WMI还可以实现许多的有关windows的系统信息,以下为wmi的官方链接,如有需要请猛击吧:

http://timgolden.me.uk/python/wmi/index.html