Discussion:
problem querying WMI in a background thread
Tim Golden
2004-11-02 08:46:20 UTC
Permalink
[dr_burrito at yahoo.com]
| I'm using Tim Golden's WMI implementation
| (http://tgolden.sc.sabren.com/python/wmi.html) version 0.6 along with
| pywin32 build 202. I'm able to successfully query WMI in the main
| thread but not in a separate thread.
|
| Here's a little snippet of sample code that fails for me:

[... snip example ...]

Well, I'm going to be mildly unhelpful, and say that I
don't strictly understand why your code doesn't work.
The thing which usually bites when using WMI and threads
is the CoInitialize trap, but it usually comes out as
an explicit "Must call CoInitialize" exception rather
than as a random COM error. At the end of the day, the
plumbing in WMI is just COM/DCOM so most things comes
down to issues of COM and threading.

But, to me more helpful, the example below does work,
so maybe you can work backwards from it.

<code>
import pythoncom
import wmi
import threading

class Info (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
Info ().start ()
</code>

TJG

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. 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
________________________________________________________________________
Fazan
2004-11-01 18:48:01 UTC
Permalink
I'm using Tim Golden's WMI implementation
(http://tgolden.sc.sabren.com/python/wmi.html) version 0.6 along with
pywin32 build 202. I'm able to successfully query WMI in the main
thread but not in a separate thread.

Here's a little snippet of sample code that fails for me:
----
import thread, threading, wmi

def wmiTest(c, callee):
print "callee: " + callee
processList = c.Win32_Process()
print "num processes: %d" % len(processList)

if __name__ == '__main__':
c = wmi.WMI()
# invoke WMI in the main thread
wmiTest(c, "main thread")

# invoke WMI in a separate thread
thread.start_new_thread(wmiTest, (c, "new thread", ))
threading.Event().wait(2)
----

And here's the output:
----
callee: main thread
num processes: 57
callee: new thread
Unhandled exception in thread started by <function wmiTest at
0x009F7E30>
Traceback (most recent call last):
File "test.py", line 5, in wmiTest
processList = c.Win32_Process()
File "C:\svn\project\tool\wmi\0.6\wmi.py", line 404, in __call__
return self.wmi.query (wql)
File "C:\svn\project\tool\wmi\0.6\wmi.py", line 583, in query
raise WMI_EXCEPTIONS.get (hresult, x_wmi (hresult))
wmi.x_wmi: -2147352567
----

Notice that calling wmiTest() from the main thread works and the list
of Win32_Process objects is returned. Calling it using
thread.start_new_thread() causes an exception to be thrown. I've also
tried instantiating the WMI object inside wmiTest() instead of passing
it in as a parameter; this also fails but with a different exception.

Has anyone seen this type of problem before? TIA
Fazan
2004-11-03 01:31:43 UTC
Permalink
Indeed, calling pythoncom.CoInitialize() before instantiating WMI
seems to do the trick. Thanks!
Post by Tim Golden
[dr_burrito at yahoo.com]
| I'm using Tim Golden's WMI implementation
| (http://tgolden.sc.sabren.com/python/wmi.html) version 0.6 along with
| pywin32 build 202. I'm able to successfully query WMI in the main
| thread but not in a separate thread.
|
[... snip example ...]
Well, I'm going to be mildly unhelpful, and say that I
don't strictly understand why your code doesn't work.
The thing which usually bites when using WMI and threads
is the CoInitialize trap, but it usually comes out as
an explicit "Must call CoInitialize" exception rather
than as a random COM error. At the end of the day, the
plumbing in WMI is just COM/DCOM so most things comes
down to issues of COM and threading.
But, to me more helpful, the example below does work,
so maybe you can work backwards from it.
<code>
import pythoncom
import wmi
import threading
threading.Thread.__init__ (self)
print 'In Another Thread...'
pythoncom.CoInitialize ()
c = wmi.WMI ()
print process.ProcessId, process.Name
print 'In Main Thread'
c = wmi.WMI ()
print process.ProcessId, process.Name
Info ().start ()
</code>
TJG
________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
http://www.star.net.uk
________________________________________________________________________
Loading...