On 9/14/06, Mark Hammond <[EMAIL PROTECTED]> wrote:
Basically, you must:
* Arrange for your process to be started
* In your process, create a COM server object - ie, create an object with
the _public_methods_ etc attributes, then use win32com.server.wrap to wrap
it
* Call pythoncom.RegisterActiveObject passing it this object.

That should be enough to have GetObject attach to your instance.

Thanks for the clues. I had trouble getting my app to do anything in
response to COM messages, but some further digging revealed
pythoncom.PumpWaitingMessages, which the event loop could poll or or
it could run in a separate thread.

I will write this up as a recipe in the Python Cookbook; any comments
on my code (attached)?

Thanks again!

--
David Goodger <http://python.net/~goodger>
import os
import time
import pythoncom
import win32com.server.util
import win32com.server.register

"""
Test of a long-running Python COM server as part of a larger, independent
application.  The same server object is reused for each COM message.

Setup::

    import comtest
    comtest.register()

Test: run as a script from the command-line or::

    import comtest
    comtest.main()

Teardown::

    import comtest
    comtest.unregister()

The following VBA code will connect to the already running Python process::

    Sub PythonTest()
        On Error Resume Next
        Set comobj = GetObject(, "Python.COMTest")
        If Err.Number <> 0 Then
            AppNotRunning = True
            Err.Clear
            MsgBox Err.Number
        Else
            On Error GoTo 0
            MsgBox comobj.Get()
            resp = comobj.Set("Loops=" + Str(comobj.GetLoops()))
            MsgBox comobj.GetLoops()
            MsgBox comobj.Get()
            MsgBox comobj.GetLoops()
            resp = comobj.Quit()
        End If
    End Sub
"""

class COMTest:

    _public_methods_ = ['Set', 'Get', 'GetLoops', 'Quit']
    _reg_progid_ = 'Python.COMTest'
    _reg_clsid_ = '{9C4F2666-2F0C-41BC-BBA0-78440FF9794A}'

    quit = False
    loops = 0
    val = None

    def Set(self, val):
        self.val = val

    def Get(self):
        return self.val

    def GetLoops(self):
        return self.loops

    def Quit(self):
        self.quit = True


def register():
    """This only needs to be run once."""
    print 'Registering COM server (CLSID=%s)' % COMTest._reg_clsid_
    win32com.server.register.RegisterClasses(COMTest)

def unregister():
    print 'Unregistering COM server (CLSID=%s)' % COMTest._reg_clsid_
    win32com.server.register.UnregisterClasses(COMTest)

def main():
    if os.path.exists('comtest.exit'):
        os.unlink('comtest.exit')
    print 'Registering COM server object as active'
    obj = COMTest()
    wrapped = win32com.server.util.wrap(obj)
    handle = pythoncom.RegisterActiveObject(wrapped, obj._reg_clsid_, 0)
    # Pretend to be busy until it's time to quit:
    while not (obj.quit or os.path.exists('comtest.exit')):
        # Periodically hand over control to pythoncom:
        pythoncom.PumpWaitingMessages()
        obj.loops += 1
        time.sleep(.1)
    print 'Revoking COM server active object registration'
    pythoncom.RevokeActiveObject(handle)


if __name__ == '__main__':
    main()
_______________________________________________
Python-win32 mailing list
Python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to