Board logo

标题: [原创教程] Python wmi Cookbook 中文翻译 [打印本页]

作者: HAT    时间: 2012-4-8 13:15     标题: Python wmi Cookbook 中文翻译

本文由HAT根据英文版《wmi Cookbook》http://timgolden.me.uk/python/wmi/cookbook.html翻译而来,转载请注明出处。

简介:

本文所有的例均是假设你在使用来自http://timgolden.me.uk/python/wmi.html的WMI模块。使用此模块,你可以在Windows系统中去体验下面这些实用的例子。或许你将由此了解到WMI的冰山一角。

下面这些例子,除非有特别说明,均假设你要连接的是当前的机器。如果要连接远程机器,只需要在WMI构造器中指定远程机器名即可:

  1. import wmi
  2. c = wmi.WMI ("some_other_machine")
复制代码


注:这都是些完整的例子,你可以直接复制粘贴到一个.py文件里面,也可以复制粘贴到Python命令行交互窗口(原文作者是在Windows2000系统的CMD窗口做的测试)。

实例:

列出所有正在运行的进程

  1. import wmi
  2. c = wmi.WMI ()
  3. for process in c.Win32_Process ():
  4.   print process.ProcessId, process.Name
复制代码


列出所有正在运行的记事本进程

  1. import wmi
  2. c = wmi.WMI ()
  3. for process in c.Win32_Process (name="notepad.exe"):
  4.   print process.ProcessId, process.Name
复制代码


创建一个新的记事本进程然后结束它

  1. import wmi
  2. c = wmi.WMI ()
  3. process_id, return_value = c.Win32_Process.Create (CommandLine="notepad.exe")
  4. for process in c.Win32_Process (ProcessId=process_id):
  5.   print process.ProcessId, process.Name
  6. result = process.Terminate ()
复制代码


显示Win32_Process类的.Create方法的接口

注:wmi模块会接受WMI方法的传入参数作为Python的关键字参数,并把传出参数作为一个元组进行返回。

  1. import wmi
  2. c = wmi.WMI ()
  3. print c.Win32_Process.Create
复制代码


显示没有处于正常运行状态的自启动服务

  1. import wmi
  2. c = wmi.WMI ()
  3. stopped_services = c.Win32_Service (StartMode="Auto", State="Stopped")
  4. if stopped_services:
  5.   for s in stopped_services:
  6.     print s.Caption, "service is not running"
  7. else:
  8.   print "No auto services stopped"
复制代码


显示每个固定磁盘的剩余空间百分比

  1. import wmi
  2. c = wmi.WMI ()
  3. for disk in c.Win32_LogicalDisk (DriveType=3):
  4.   print disk.Caption, "%0.2f%% free" % (100.0 * long (disk.FreeSpace) / long (disk.Size))
复制代码


运行记事本,等它关闭之后显示它里面的文字

注:这个例子是运行一个进程并且知道它什么时候结束,而不是去处理输入到记事本里面的文字。所以我们只是简单的用记事本打开一个指定文件,等到用户完成输入并关闭记事本之后,显示一下它的内容。

本例不适用于远程机器,因为处于安全考虑,在远程机器上启动的进程是没有界面的(你在桌面上是看不到它们的)。这类远程操作的技术多用于在服务器上运行一个安装程序,安装结束之后重启机器。

  1. import wmi
  2. c = wmi.WMI ()
  3. filename = r"c:\temp\temp.txt"
  4. process = c.Win32_Process
  5. process_id, result = process.Create (CommandLine="notepad.exe " + filename)
  6. watcher = c.watch_for (
  7.   notification_type="Deletion",
  8.   wmi_class="Win32_Process",
  9.   delay_secs=1,
  10.   ProcessId=process_id
  11. )
  12. watcher ()
  13. print "This is what you wrote:"
  14. print open (filename).read ()
复制代码

作者: HAT    时间: 2012-4-8 13:16

监视新的打印任务
  1. import wmi
  2. c = wmi.WMI ()
  3. print_job_watcher = c.Win32_PrintJob.watch_for (
  4.   notification_type="Creation",
  5.   delay_secs=1
  6. )
  7. while 1:
  8.   pj = print_job_watcher ()
  9.   print "User %s has submitted %d pages to printer %s" % \
  10.     (pj.Owner, pj.TotalPages, pj.Name)
复制代码
重启远程机器

注:要对远程系统进行这样的操作,WMI脚本必须具有远程关机(RemoteShutdown)的权限,也就是说你必须在连接别名中进行指定。WMI构造器允许你传入一个完整的别名,或者是指定你需要的那一部分。使用wmi.WMI.__init__的帮助文档可以找到更多相关内容。
  1. import wmi
  2. # other_machine = "machine name of your choice"
  3. c = wmi.WMI (computer=other_machine, privileges=["RemoteShutdown"])
  4. os = c.Win32_OperatingSystem (Primary=1)[0]
  5. os.Reboot ()
复制代码
对于启用IP的网卡显示其IP和MAC地址
  1. import wmi
  2. c = wmi.WMI ()
  3. for interface in c.Win32_NetworkAdapterConfiguration (IPEnabled=1):
  4.   print interface.Description, interface.MACAddress
  5.   for ip_address in interface.IPAddress:
  6.     print ip_address
  7.   print
复制代码
查看自启动项
  1. import wmi
  2. c = wmi.WMI ()
  3. for s in c.Win32_StartupCommand ():
  4.   print "[%s] %s <%s>" % (s.Location, s.Caption, s.Command)
复制代码
监视事件日志中的错误信息
  1. import wmi
  2. c = wmi.WMI (privileges=["Security"])
  3. watcher = c.watch_for (
  4.   notification_type="Creation",
  5.   wmi_class="Win32_NTLogEvent",
  6.   Type="error"
  7. )
  8. while 1:
  9.   error = watcher ()
  10.   print "Error in %s log: %s" %  (error.Logfile, error.Message)
  11.   # send mail to sysadmin etc.
复制代码
列出注册表子键

注:本例及以下几例使用了Registry()这个方便的函数,此函数是早期加入到wmi包的,它等效于:
import wmi
r = wmi.WMI (namespace="DEFAULT").StdRegProv
  1. import _winreg
  2. import wmi
  3. r = wmi.Registry ()
  4. result, names = r.EnumKey (
  5.   hDefKey=_winreg.HKEY_LOCAL_MACHINE,
  6.   sSubKeyName="Software"
  7. )
  8. for key in names:
  9.   print key
复制代码
增加一个新的注册表子键
  1. import _winreg
  2. import wmi
  3. r = wmi.Registry ()
  4. result, = r.CreateKey (
  5.   hDefKey=_winreg.HKEY_LOCAL_MACHINE,
  6.   sSubKeyName=r"Software\TJG"
  7. )
复制代码
增加一个新的注册表键值
  1. import _winreg
  2. import wmi
  3. r = wmi.Registry ()
  4. result, = r.SetStringValue (
  5.   hDefKey=_winreg.HKEY_LOCAL_MACHINE,
  6.   sSubKeyName=r"Software\TJG",
  7.   sValueName="ApplicationName",
  8.   sValue="TJG App"
  9. )
复制代码

作者: HAT    时间: 2012-4-8 13:18

创建一个新的IIS站点
  1. import wmi
  2. c = wmi.WMI (namespace="MicrosoftIISv2")
  3. #
  4. # Could as well be achieved by doing:
  5. #  web_server = c.IISWebService (Name="W3SVC")[0]
  6. #
  7. for web_server in c.IIsWebService (Name="W3SVC"):
  8.   break
  9. binding = c.new ("ServerBinding")
  10. binding.IP = ""
  11. binding.Port = "8383"
  12. binding.Hostname = ""
  13. result, = web_server.CreateNewSite (
  14.   PathOfRootVirtualDir=r"c:\inetpub\wwwroot",
  15.   ServerComment="My Web Site",
  16.   ServerBindings= [binding.ole_object]
  17. )
复制代码
显示共享目录
  1. import wmi
  2. c = wmi.WMI ()
  3. for share in c.Win32_Share ():
  4.   print share.Name, share.Path
复制代码
显示打印任务
  1. import wmi
  2. c = wmi.WMI ()
  3. for printer in c.Win32_Printer ():
  4.   print printer.Caption
  5.   for job in c.Win32_PrintJob (DriverName=printer.DriverName):
  6.     print "  ", job.Document
  7.   print
复制代码
显示磁盘分区
  1. import wmi
  2. c = wmi.WMI ()
  3. for physical_disk in c.Win32_DiskDrive ():
  4.   for partition in physical_disk.associators ("Win32_DiskDriveToDiskPartition"):
  5.     for logical_disk in partition.associators ("Win32_LogicalDiskToPartition"):
  6.       print physical_disk.Caption, partition.Caption, logical_disk.Caption
复制代码
安装一个产品
  1. import wmi
  2. c = wmi.WMI ()
  3. c.Win32_Product.Install (
  4.   PackageLocation="c:/temp/python-2.4.2.msi",
  5.   AllUsers=False
  6. )
复制代码
使用指定用户名连接另一台机器

注:你不能使用这个方法连接本机
  1. import wmi
  2. #
  3. # Using wmi module before 1.0rc3
  4. #
  5. connection = wmi.connect_server (
  6.   server="other_machine",
  7.   user="tim",
  8.   password="secret"
  9. )
  10. c = wmi.WMI (wmi=connection)
  11. #
  12. # Using wmi module at least 1.0rc3
  13. #
  14. c = wmi.WMI (
  15.   computer="other_machine",
  16.   user="tim",
  17.   password="secret"
  18. )
复制代码
显示一个方法的签名
  1. import wmi
  2. c = wmi.WMI ()
  3. for opsys in c.Win32_OperatingSystem ():
  4.   break
  5. print opsys.Reboot
  6. print opsys.Shutdown
复制代码

作者: HAT    时间: 2012-4-8 13:20

创建任务计划

注:WMI的ScheduledJob类相当于Windows的AT服务(通过at命令来控制)。
  1. import os
  2. import wmi
  3. c = wmi.WMI ()
  4. one_minutes_time = datetime.datetime.now () + datetime.timedelta (minutes=1)
  5. job_id, result = c.Win32_ScheduledJob.Create (
  6.   Command=r"cmd.exe /c dir /b c:\ > c:\\temp.txt",
  7.   StartTime=wmi.from_time (one_minutes_time)
  8. )
  9. print job_id
  10. for line in os.popen ("at"):
  11.   print line
复制代码
以最小化的方式运行一个进程
  1. import wmi
  2. SW_SHOWMINIMIZED = 1
  3. c = wmi.WMI ()
  4. startup = c.Win32_ProcessStartup.new (ShowWindow=SW_SHOWMINIMIZED)
  5. pid, result = c.Win32_Process.Create (
  6.   CommandLine="notepad.exe",
  7.   ProcessStartupInformation=startup
  8. )
  9. print pid
复制代码
查看磁盘类型
  1. import wmi
  2. DRIVE_TYPES = {
  3.   0 : "Unknown",
  4.   1 : "No Root Directory",
  5.   2 : "Removable Disk",
  6.   3 : "Local Disk",
  7.   4 : "Network Drive",
  8.   5 : "Compact Disc",
  9.   6 : "RAM Disk"
  10. }
  11. c = wmi.WMI ()
  12. for drive in c.Win32_LogicalDisk ():
  13.   print drive.Caption, DRIVE_TYPES[drive.DriveType]
复制代码
列出命名空间
  1. import wmi
  2. def enumerate_namespaces (namespace=u"root", level=0):
  3.   print level * "  ", namespace.split ("/")[-1]
  4.   c = wmi.WMI (namespace=namespace)
  5.   for subnamespace in c.__NAMESPACE ():
  6.     enumerate_namespaces (namespace + "/" + subnamespace.Name, level + 1)
  7. enumerate_namespaces ()
复制代码
在线程中使用WMI

注:WMI技术是基于COM的,要想在线程中使用它,你必须初始化COM的线程模式,就算你要访问一个隐式线程化的服务也是如此。
  1. import pythoncom
  2. import wmi
  3. import threading
  4. import time
  5. class Info (threading.Thread):
  6.   def __init__ (self):
  7.     threading.Thread.__init__ (self)
  8.   def run (self):
  9.     print 'In Another Thread...'
  10.     pythoncom.CoInitialize ()
  11.     try:
  12.       c = wmi.WMI ()
  13.       for i in range (5):
  14.         for process in c.Win32_Process ():
  15.           print process.ProcessId, process.Name
  16.         time.sleep (2)
  17.     finally:
  18.       pythoncom.CoUninitialize ()
  19. if __name__ == '__main__':
  20.   print 'In Main Thread'
  21.   c = wmi.WMI ()
  22.   for process in c.Win32_Process ():
  23.     print process.ProcessId, process.Name
  24.   Info ().start ()
复制代码

作者: HAT    时间: 2012-4-8 13:22

监控多台机器的电源事件

注:这个例子演示了外部事件、线程、远程监控等,所有这些都在一个小小的包里面!无论一台机器何时进入或退出挂起状态,电源子系统都会通过WMI产生一个外部事件。外部事件是非常有用的,因为WMI不必轮询也可以保证你不会错过任何事件。这里的多台机器只是使用进程的一个实际例子而已。
  1. import pythoncom
  2. import wmi
  3. import threading
  4. import Queue
  5. class Server (threading.Thread):
  6.   def __init__ (self, results, server, user, password):
  7.     threading.Thread.__init__ (self)
  8.     self.results = results
  9.     self.server = server
  10.     self.user = user
  11.     self.password = password
  12.     self.setDaemon (True)
  13.   def run (self):
  14.     pythoncom.CoInitialize ()
  15.     try:
  16.       #
  17.       # If you don't want to use explicit logons, remove
  18.       # the user= and password= params here and ensure
  19.       # that the user running *this* script has sufficient
  20.       # privs on the remote machines.
  21.       #
  22.       c = wmi.WMI (self.server, user=self.user, password=self.password)
  23.       power_watcher = c.Win32_PowerManagementEvent.watch_for ()
  24.       while True:
  25.         self.results.put ((self.server, power_watcher ()))
  26.     finally:
  27.       pythoncom.CoUninitialize ()
  28. #
  29. # Obviously, change these to match the machines
  30. # in your network which probably won't be named
  31. # after Harry Potter characters. And which hopefully
  32. # use a less obvious admin password.
  33. #
  34. servers = [
  35.   ("goyle", "administrator", "secret"),
  36.   ("malfoy", "administrator", "secret")
  37. ]
  38. if __name__ == '__main__':
  39.   power_events = Queue.Queue ()
  40.   for server, user, password in servers:
  41.     print "Watching for", server
  42.     Server (power_events, server, user, password).start ()
  43.   while True:
  44.     server, power_event = power_events.get ()
  45.     print server, "=>", power_event.EventType
复制代码
查看当前的墙纸
  1. import wmi
  2. import win32api
  3. import win32con
  4. c = wmi.WMI ()
  5. full_username = win32api.GetUserNameEx (win32con.NameSamCompatible)
  6. for desktop in c.Win32_Desktop (Name=full_username):
  7.   print \
  8.     desktop.Wallpaper or "[No Wallpaper]", \
  9.     desktop.WallpaperStretched, desktop.WallpaperTiled
复制代码





欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2