[python-win32] COM: Minimal example of a custom server working with DispatchWithEvents()

Mark Hammond mhammond at skippinet.com.au
Sat Jul 31 21:36:38 EDT 2021


On 1/08/2021 12:21 am, William Belanger wrote:
> Hi,
> 
> 
> Thank you for the follow up. Perhaps I did not express my need clearly 
> enough, so I made this minimal example;
> 
> 
>     # https://gitlab.com/-/snippets/2155778
>     <https://gitlab.com/-/snippets/2155778>
> 
>     import pythoncom
>     import sys
>     import threading
>     import win32com.client
>     import win32com.server.util
>     from win32com.server import localserver
> 
> 
>     def init_server():
>     pythoncom.CoInitialize()
>     localserver.serve(["{D390AE78-D6A2-47CF-B462-E4F2DC9C70F5}"])
> 
> 
>     class Main:
>     def __init__(self):
>     self.server = win32com.client.Dispatch("Minimal.Example")
>     self.server.parent = self # TypeError: must be real number, not Main

That exception is very odd and I should look into it - but the problem 
here is that you are trying to set an attribute on a COM object which is 
a Python instance, which doesn't really make sense. What you want is to 
set it to a COM object - which `self` is not. So something like:


class Main:
     _public_methods_ = ["pong"]
     def __init__(self):
         self.server = win32com.client.Dispatch("Minimal.Example")
         self.server.parent = win32com.server.util.wrap(self)
         self.server.Ping()

     def pong(self):
         return "pong"

works. Sadly another paper-cut here is that the server just sees this as 
a plain IDispatch object rather than a `Dispatch` wrapper - so `Ping` 
needs to look something like:

     def Ping(self):
         parent_as_object = win32com.client.Dispatch(self.parent)
         print(parent_as_object.pong())

I guess you could, say, change `parent` into `set_parent()`, or 
intercept via __setattr__() and do the wrapping just once.

HTH,

Mark


More information about the python-win32 mailing list