Importing WMI in a child Thread throws an error

K

kyosohma

Hi,

I am trying to create a post logon script which does various tasks,
like setup a printer based on location. While most of it works very
fast, I have a second Python script that I run that scans the PC using
WMI (among other things) and writes the following to a database: Name,
Username, Machine, IP, Login Date,CPU,Memory.

The problem I have is that since I import WMI, it takes a long time
and we have users complaining about it. So I stuck the import
statement into a separate thread and set it to a daemon so it could do
its thing in the background and the rest of the script would finish
and exit.

Unfortunately, I get the following error when I do this:

Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python24\lib\threading.py", line 444, in __bootstrap
self.run()
File "C:\Python24\lib\threading.py", line 424, in run
self.__target(*self.__args, **self.__kwargs)
File "//serverName/Scripts/PostLogon_MT.py", line 35, in InvThread
import db_inventory
File "\\serverName\PythonPackages\Utilities\db_inventory.py", line
3, in ?
import wmi
File "C:\Python24\lib\site-packages\wmi.py", line 204, in ?
obj = GetObject ("winmgmts:")
File "C:\Python24\lib\site-packages\win32com\client\__init__.py",
line 73, in GetObject
return Moniker(Pathname, clsctx)
File "C:\Python24\lib\site-packages\win32com\client\__init__.py",
line 88, in Moniker
moniker, i, bindCtx = pythoncom.MkParseDisplayName(Pathname)
com_error: (-2147221020, 'Invalid syntax', None, None)

If I import the module without using threading, it works fine, but
takes forever. Even after it threw that error above, the process
didn't stop and I had to kill it with a control+C.

I am using Windows XP with Python 2.4. Thanks for any help you can
give.

Mike
 
T

Tim Golden

The problem I have is that since I import WMI, it takes a long time
and we have users complaining about it. So I stuck the import
statement into a separate thread and set it to a daemon so it could do
its thing in the background and the rest of the script would finish
and exit.

Two things:

1) If you run WMI in a thread, you'll need to call
pythoncom.CoInitialize first:

<code>
import pythoncom
import wmi

pythoncom.CoInitialize ()
c = wmi.WMI ()
#
# do things
#
pythoncom.CoUninitialize ()
</code>

2) If you need a bit of speed running WMI, see the post
I sent a few days ago to someone else:

http://mail.python.org/pipermail/python-win32/2007-February/005550.html

TJG
 
K

kyosohma

Two things:

1) If you run WMI in a thread, you'll need to call
pythoncom.CoInitialize first:

<code>
import pythoncom
import wmi

pythoncom.CoInitialize ()
c = wmi.WMI ()
#
# do things
#
pythoncom.CoUninitialize ()
</code>

2) If you need a bit of speed running WMI, see the post
I sent a few days ago to someone else:

http://mail.python.org/pipermail/python-win32/2007-February/005550.html

TJG

Thanks! This works for my problem. It appears to cut the real time
required for my script to run by 30-50%. I tried to figure out how to
apply your answer to the other fellow, but I am actually querying WMI
for the amount of RAM and the CPU type and I just don't see how to use
your example in these cases. I am new to the WMI paradigm.

Thanks again,

Mike
 
T

Tim Golden

Thanks! This works for my problem. It appears to cut the real time
required for my script to run by 30-50%. I tried to figure out how to
apply your answer to the other fellow, but I am actually querying WMI
for the amount of RAM and the CPU type and I just don't see how to use
your example in these cases. I am new to the WMI paradigm.

If you want to post some specific code examples, I'm
happy to talk you through possible optimisations.

TJG
 
K

kyosohma

If you want to post some specific code examples, I'm
happy to talk you through possible optimisations.

TJG

Sorry I didn't reply right away. Here's the straight WMI code I'm
using:

c = wmi.WMI()
for i in c.Win32_ComputerSystem():
mem = int(i.TotalPhysicalMemory)
compname = i.Name
for i in c.Win32_Processor ():
cputype = i.Name

This code was wrapped in your CoInitialize com objects.

Let me know if you need more code.

Mike
 
T

Tim Golden

If you want to post some specific code examples, I'm
Sorry I didn't reply right away. Here's the straight WMI code I'm
using:

c = wmi.WMI()
for i in c.Win32_ComputerSystem():
mem = int(i.TotalPhysicalMemory)
compname = i.Name
for i in c.Win32_Processor ():
cputype = i.Name

Well, don't know how much gain you'll get, but yo
could try the following quickies:

<code>
import wmi
c = wmi.WMI (find_classes=False)

for i in c.Win32_ComputerSystem (
['TotalPhysicalMemory', 'Name']
):
mem = int (i.TotalPhysicalMemory)
compnam = i.Name

for i in c.Win32_Processor (['Name']):
cputype = i.Name

</code>

If you were going to repeat these often (say, in
a loop, which doesn't seem likely given you
examples) you might gain a few nanosecs by
pulling the attribute lookup outside the loop:

<code>
import wmi
c = wmi.WMI (find_classes=False)

ComputerSystem = c.Win32_ComputerSystem
Processor = c.Win32_Processor

while True:
for computer_system in ComputerSystem (...): ...
for processor in Processor (...): ...

</code>

But, as everyone else on this list will tell you,
there's no point in optimising unless you know you
need to to, and unless you know where :) That's
what modules like timeit profiler are for.

TJG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top