How to use multiple instances of the same COM object at the same time

Jan jan-A at T-prox.be
Fri Mar 22 19:13:50 CET 2013


Dear Usenet readers,

Our company wants to implement about 40 biometric access control devices 
which have a proprietary DLL with a COM object in it.

I've done some research about COM objects and how to use them.
Now, I need to connect to every device separately and register for real 
time events.  So, I need about 40 instances of the COM object 
simultaneously connected and registered to catch all events of all devices.

I assumed I needed threading for this, and I have done a simple 
implementation.

All I want to ask is: Does anybody see something that I could have done 
in a better way? I'm new to COM objects in Python!

The program runs fine, it is very basic and I tested it with 3 devices 
connected at the same time.  In production this will be 40!

Thanks in advance

Jan

Source code:

# Based on eventappartmentthreading from the win32com demo

import sys, os, time
import win32com.client
import win32api
import win32event
# sys.coinit_flags not set, so pythoncom initializes apartment-threaded.
import pythoncom
from threading import Thread

threadlist = dict() # this stores the device ids
                     # using the threadid as the key field

class ZkEvents:
     def __init__(self):
         self.event = win32event.CreateEvent(None, 0, 0, None)
         thread = win32api.GetCurrentThreadId()
         print "thread %s " % thread

         self.dev_id = threadlist[thread]
         print "Thread Connected For ID %s " % self.dev_id

     def OnFinger(self):
         print self.dev_id,
         print "OnFinger"

     def OnVerify(self, iUserID=pythoncom.Empty):
         print self.dev_id,
         print "OnVerify: %s" % iUserID

     def OnKeyPress(self, iKey=pythoncom.Empty):
         print self.dev_id,
         print "KeyPress: %s" % iKey

def WaitWhileProcessingMessages(event, timeout = 60):
     start = time.clock()
     while True:
         # Wake 4 times a second - we can't just specify the
         # full timeout here, as then it would reset for every
         # message we process.
         rc = win32event.MsgWaitForMultipleObjects( (event,), 0,
                                 250,
                                 win32event.QS_ALLEVENTS)
         if rc == win32event.WAIT_OBJECT_0:
             # event signalled - stop now!
             return True
         if (time.clock() - start) > timeout:
             # Timeout expired.
             return False
         # must be a message.
         pythoncom.PumpWaitingMessages()

def TestZkEvents(ip, dev_id):
     thread = win32api.GetCurrentThreadId()
     print 'TestZkEvents created ZK object on thread %d'%thread
     threadlist[thread] = dev_id

     pythoncom.CoInitialize()
     zk = win32com.client.DispatchWithEvents("zkemkeeper.ZKEM", ZkEvents)

     if zk.Connect_Net(ip, 4370):
         print "Connect %s OK" % ip
     else:
         print "Connect %s Failed" % ip
     try:
         if zk.RegEvent(1, 65535): # 65535 = register for all events
             print "RegEvent %s, %s OK" % (ip, dev_id)
         else:
             print "RegEvent %s, %s Failed" % (ip, dev_id)
     except pythoncom.com_error, details:
         print "Warning - could not open the test HTML file", details

     # Wait for the event to be signaled while pumping messages.
     while True:
         if not WaitWhileProcessingMessages(zk.event):
             print "No Events From %s During Last Minute" % dev_id

     zk = None

if __name__=='__main__':
     # this should be a for loop with database fields...
     t1 = Thread(target=TestZkEvents, args=('192.168.1.211',40))
     t1.start()

     t2 = Thread(target=TestZkEvents, args=('192.168.1.212',45))
     t2.start()

     t3 = Thread(target=TestZkEvents, args=('192.168.1.213',49))
     t3.start()




More information about the Python-list mailing list