Using Python with COM to communicate with proprietary Windows software

Paul Casteels Paul.Casteels at ua.ac.be
Wed Sep 21 15:05:59 CEST 2005


Joakim Persson wrote:
> On Tue, 13 Sep 2005 10:15:18 +0200, Thomas Heller <theller at python.net>
> wrote:
> 
> 
>>>This _shouldn't_ be too difficult -- I know which methods must be
>>>implemented (basically just some kind of event handling to deal with
>>>randomly arriving log points, should be implemented as "onMsg()" on my
>>>COM server side, and some other similar methods), but I don't really
>>>know how. I have tried doing simple COM servers using win32com, but is
>>>it equally possible to implement such a simple thing in comtypes? I
>>>didn't find any server side examples in comtypes, but perhaps there is
>>>a way?
>>
>>There is not yet any server support in comtypes, but it will be added.
>>In the meantime you could use the ctypes.com package that is included in
>>ctypes itself, there are even samples.
>>
>>Thomas
> 
> 
> Thank you, I will try that. Right now I've been trying to use win32com
> for the server creation, but I haven't been successful yet (have not
> explored it that much yet though). 
> 
> I have registered a COM server (it should only implement two methods,
> "onMsg()" and "onNotify()", which should print whatever is sent to
> them directly to stdout), but I need to create an interface which is
> not an IDispatch interface and pass it on to the proprietary COM
> server. This connection is needed so that the proprietary COM server
> knows where to send the log and control data. 
> 
> Registering the COM object in the registry works fine, but how do I
> make it look like a custom interface from the proprietary COM servers
> point of view? Oh well, I will look at it some more tomorrow and
> hopefully come up with a solution...
> 
Hi Joakim,

  This server I wrote for the Palm Desktop with win32com, it creates a none IDispatch COMserver.
  Maybe it can be of help. I am interested in what you find out on this.

Regards,

	Paul Casteels


import pythoncom
import pywintypes
import winerror
import types,time,string
import win32com
import win32ui,win32con
import rfc822
import XmlWriter

from win32com.server.exception import COMException
from win32com.server.util import wrap
from win32com.client import gencache,Dispatch,constants
from win32com import universal



# The following 3 lines may need tweaking for the particular server
# Candidates are pythoncom.Missing and pythoncom.Empty
defaultNamedOptArg=pythoncom.Missing
defaultNamedNotOptArg=pythoncom.Missing
defaultUnnamedArg=pythoncom.Missing

palmApp = 0
outfileName = r'c:\Documents And Settings\paul\My Documents\Python\PDA\cal2.xml'

universal.RegisterInterfaces('{C9B354D8-4A1C-11D5-81D2-00C04FA03755}', 0, 1, 0, ["IDesktopAddin"])
universal.RegisterInterfaces('{C9B354D8-4A1C-11D5-81D2-00C04FA03755}', 0, 1, 0, ["IDesktopCommand"])

def d2s(inDate):
     return rfc822.mktime_tz(rfc822.parsedate_tz(inDate))
def s2d(inDate):
     return time.asctime(time.localtime(inDate))



class DesktopCommand:
     global palmApp

     _public_methods_ = ['OnCommand']
     _com_interfaces_ = ['IDesktopCommand']

     def OnCommand(self):
         print "Hello, command"
         print palmApp
         win32ui.MessageBox("PC-Hello","PC-Title",win32con.MB_OK )

class DesktopAddin:
     _public_methods_ = ['GetFrameworkVersion',
                         'OnInitialize',
                         'OnUninitialize',
                         'ShowAboutBox',
                         'ShowProperties']
     _reg_progid_ = "PythonPalm.DesktopAddin"
     _reg_clsid_ = "{6F36C1D4-571C-484E-B47B-61297761B3D1}"
     _com_interfaces_ = ['IDesktopAddin']

     def GetFrameworkVersion(self, plVersion=defaultNamedNotOptArg):
         """method GetFrameworkVersion"""
         return 2

     def OnInitialize(self, pUnk=defaultNamedNotOptArg, dwCookie=defaultNamedNotOptArg, \
                      dwDesktopVersion=defaultNamedNotOptArg, lParam=defaultNamedNotOptArg, \
                      pbSuccess=defaultNamedNotOptArg):
         """method OnInitialize"""
         global palmApp
         self.cookie = dwCookie
         palmApp = Dispatch(pUnk)
         # add a command
         self.cmd = wrap(DesktopCommand())
         addinMgr = palmApp.AddinManager
         cmdId = 0
         cmdId = addinMgr.AddAddinCommand(self.cookie, "AddressCommand", \
                                 self.cmd, cmdId)
         cmdDesc = "&Address Command"
#        & vbTab & _
#          "Displays a list of 10 contacts." & vbTab & _
#          "Displays 10 contacts"

         addinMgr.AddAddinCommandDetails(cmdId, 0, 0, cmdDesc, constants.ePimAddressBook)

         # no data here yet available
         return 1

     def OnUninitialize(self):
         """method OnUninitialize"""
         global palmApp

         of = XmlWriter.XmlFile(outfileName,palmApp.CurrentUser.Name)

         dbPim = palmApp.DateBookPim
         startDate = '1 Jan 2000 0:0:0'
         endDate = '1 Jan 2010 0:0:0'
         events = dbPim.Events(d2s(startDate),d2s(endDate))
         for j in range(events.Count):
             startDate = time.localtime(events[j].StartTime)
             day = of.day(startDate)
             app = {}
             app['description'] = events[j].Description
             if events[j].Untimed:
                 app['untimed'] = 1
             else:
                 app['untimed'] = 0
                 app['starttime'] = s2d(events[j].StartTime)
                 app['endtime'] = s2d(events[j].EndTime)
             if events[j].Note:
                 app['note'] = events[j].Note
#            app['id'] = 'id%d' % (events[j].RecordId)
             of.appointment(app,day)
         of.close()

#        adPim = palmApp.AddressBookPim
#        contacts = adPim.Contacts("All")
#        for j in range(contacts.Count):
#            print contacts[j].LastName
         return None

     def ShowAboutBox(self, hWndParent=defaultNamedNotOptArg):
         """method ShowAboutBox"""
         print 'ShowAboutBox'
         print hWndParent
         return None

     def ShowProperties(self, hWndParent=defaultNamedNotOptArg):
         """method ShowProperties"""
         print 'ShowProperties'
         return None

     _prop_map_get_ = {
     }
     _prop_map_put_ = {
     }

if __name__ == "__main__":
     print "Registering COM server"
     import win32com.server.register
     win32com.server.register.UseCommandLine(DesktopAddin)

     print "Registering our server with Palm desktop"
     palmReg = Dispatch("PalmDesktop.RegistrationServices")
     lRegistered = palmReg.IsAddinRegistered ("PythonPalm.DesktopAddin")
     if lRegistered == 1:
         print "Removing PythonPalm.DesktopAddin"
         addinInfo = palmReg.GetAddinRegInfo("PythonPalm.DesktopAddin")
         addinInfo.Delete()
     print "Registering PythonPalm.DesktopAddin"
     palmReg.RegisterAddin ("PythonPalm.DesktopAddin","Python Addin")



More information about the Python-list mailing list