0

I've been trying to understand COM libraries but I'm still confused. If I want to make a python object com visible, the only instructions I can find are to make a python script that sets up a COM server which is invoked and used to generate class instances by name. IIUC, this is made possible by permanently adding some information to the registry that links a CLSID to the path of my server.py file; here's a minimum example:

class HelloWorld:
    # pythoncom.CreateGuid()
    _reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
    _reg_desc_ = "Python Test COM Server"
    _reg_progid_ = "PythonTestServer.HelloWorld"

    _public_methods_ = ["Hello"]
    _public_attrs_ = ["softspace", "noCalls"]
    _readonly_attrs_ = ["noCalls"]

    def __init__(self):
        self.softspace = 1
        self.noCalls = 0

    def Hello(self, who):
        self.noCalls = self.noCalls + 1
        # insert "softspace" number of spaces
        return "Hello" + " " * self.softspace + str(who)


if __name__ == "__main__": #run once to register the COM class
    import win32com.server.register

    win32com.server.register.UseCommandLine(HelloWorld) #this is what I want to avoid

Called like:

Dim a as Object = CreateObject("PythonTestServer.HelloWorld") 'late binding
a.softSpace = 10
?a.Hello("World") 'prints "Hello          World"

However I'm sure in the past I've downloaded some file.dll that I can just add as a reference to my COM client project (VBA) and I never call --register/regsrvr/etc. I assume the dll contains all the information needed to modify and revert changes to the registry at runtime. I can use Early or Late binding to create class instances. I even get intellisense if the referenced dll contains a type library.

The latter method feels much simpler and more portable. Is there a way to emulate this in python?

Greedo
  • 4,967
  • 2
  • 30
  • 78
  • You could look into registration free COM, but I doubt it will work. I have gotten registration free COM to work for Python being a client, but have never tried for Python being the server. The reason I doubt it will work for Python as the server is that Python adds several keys to the CLSID key that are specific to Python and there are no elements or attributes available in the manifest schema to hold this information. In short, I believe Python needs to read that information from the registry to know which script to run to create an object and it can't be in manifests. – Joseph Willcoxson May 04 '21 at 14:27
  • @JosephWillcoxson How do you mean? I see a few entries in the registry; namely `HKCR\{progid}\CLSID` - make it COM visible, `HKCR\AppID\{clsid}` - set some security permissions and `HKCR\CLSID\{clsid}` - which contains the info on the pythoncom server dll and location of my server.py; I guess this last one is what you are talking about and there's no standard way to register that info through a manifest? Is it very difficult to do without a manifest, considering my python script will have no COM dependencies to worry about? – Greedo May 05 '21 at 13:24
  • IDK. You'd have to dig into the code to see if it's possible. There might be some funcions in the python37.dll that are exported (or whichever version you have) and that can create an object from your script to pass to your client. I've only casually dug into Python COM stuff from questions on here. I know much more about C++ and COM. – Joseph Willcoxson May 05 '21 at 14:45

0 Answers0