[python-win32] Re: wmi + pythonservice : multithreading issue s

Tim Golden tim.golden at viacom-outdoor.co.uk
Tue Aug 31 10:39:57 CEST 2004


[Aloys Baillet]
| <code>
| import wmi
| import threading
| 
| class lmPerformancesInfos(threading.Thread):
|      def __init__(self):
|          threading.Thread.__init__(self)
|          print 'In Main Thread'
|          c = wmi.WMI ()
|          for process in c.Win32_Process ():
|            print process.ProcessId, process.Name
| 
|      def run(self):
|          print 'In Another Thread...'
|          c = wmi.WMI ()
|          while 1:
|              for process in c.Win32_Process ():
|                print process.ProcessId, process.Name
| 
| if __name__ == '__main__':
|      perfs = lmPerformancesInfos()
|      perfs.start()
| 
| </code>

[... snip resulting error ...]

Well, a couple of things occur to me here, one
definitely pertinent, the other less so. 

First, whenever you're using COM/DCOM in anything other
than the main thread of a program, you need to call 
pythoncom.CoInitialize () first. Just one of those things.

Secondly, I'm not sure that you entirely understand the
way the threading.Thread class is supposed to work. There
are, of course, several ways to do things, but the usual
approach is to create one or more subthreads from the main
program thread (ie from what you usually think of as the
program) and then to start those threads. By virtue of the
way Python works, anything in the Thread __init__ will in
effect be called in the main thread, before the subthread
has started, but it's not the most logical place.

The code below does, I believe, what your code sample
did, and doesn't give any errors. 

<code>
import pythoncom
import wmi
import threading

class lmPerformancesInfos(threading.Thread):
   def __init__(self):
     threading.Thread.__init__(self)

   def run(self):
     print 'In Another Thread...'
     pythoncom.CoInitialize ()
     c = wmi.WMI ()
     while 1:
       for process in c.Win32_Process ():
         print process.ProcessId, process.Name

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

   perfs = lmPerformancesInfos()
   perfs.start()
</code>

Having said all that, I've not encountered this particular 
problem in a service, with or without a CoInitialize. For
example, the following code works:

<code>
import os, sys
import threading
import time

import win32serviceutil
import win32service
import win32event

import wmi

class Service (win32serviceutil.ServiceFramework):
  _svc_name_ = "WMIService"
  _svc_display_name_ = "WMI Service"

  def __init__ (self, args):
    win32serviceutil.ServiceFramework.__init__ (self, args)
    self.hWaitStop = win32event.CreateEvent (None, 0, 0, None)
    self.computer = wmi.WMI ()
    open ("c:/temp/wmi-service.log", "w").write ("Started at %s\n" %
time.asctime ())

  def SvcStop (self):
    self.ReportServiceStatus (win32service.SERVICE_STOP_PENDING)
    win32event.SetEvent (self.hWaitStop)

  def SvcDoRun (self):
    while 1:
      result = win32event.WaitForSingleObject (self.hWaitStop, 5000)
      if result == win32event.WAIT_TIMEOUT:
        f = open ("c:/temp/wmi-service.log", "a")
        f.write ("%s\n" % time.asctime ())
        for i in self.computer.Win32_Process ():
          f.write ("%s\n" % i.Caption)
        f.close ()
      else:
        open ("c:/temp/wmi-service.log", "a").write ("Finished at %s\n" %
time.asctime ())
        break

if __name__ == '__main__':
  win32serviceutil.HandleCommandLine (Service)
</code>

I realise that by now you'll have implemented your performance
code some other way, but I did want to take the opportunity to
track down problems with WMI if there were any.

TJG

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________


More information about the Python-win32 mailing list