Consuming Python COM Server from .NET
.net, com, python
Solution
A COM server is just a piece of software (a DLL or an executable) that will accept remote procedure calls (RPC) through a defined protocol. Part of the protocol says that the server must have a unique ID, stored in the Windows' registry. In our case, this means that you have "registered" a server that is not existing. Thus the error (component not found).
So, it should be something like this (as usual, this is untested code!):
import pythoncom
class HelloWorld:
_reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
_reg_clsid_ = "{B83DD222-7750-413D-A9AD-01B37021B24B}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestServer"
_public_methods_ = ['Hello']
_public_attrs_ = ['softspace', 'noCalls']
_readonly_attrs_ = ['noCalls']
# for Python 3.7+
_reg_verprogid_ = "Python.TestServer.1"
_reg_class_spec_ = "HelloWorldCOM.HelloWorld"
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__':
if '--register' in sys.argv[1:] or '--unregister' in sys.argv[1:]:
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
else:
# start the server.
from win32com.server import localserver
localserver.serve(['{B83DD222-7750-413D-A9AD-01B37021B24B}'])
Then you should run from the command line (assuming the script is called HelloWorldCOM.py):
HelloWorldCOM.py --register
HelloWorldCOM.py
Class HelloWorld is the actual implementation of the server. It expose one method (Hello) and a couple of attributes, one of the two is read-only. With the first command, you register the server; with the second one, you run it and then it becomes available to usage from other applications.
Problem
I wanted to implement python com server using win32com extensions. Then consume the server from within the .NET. I used the following example to implement the com server and it runs without a problem but when I try to consume it using C# I got FileNotFoundException with the following message "Retrieving the COM class factory for component with CLSID {676E38A6-7FA7-4BFF-9179-AE959734DEBB} failed due to the following error: 8007007e." . I posted the C# code as well.I wonder if I'm missing something I would appreciate any help. Thanks, Sarah ``` #PythonCOMServer.py import pythoncom class PythonUtilities: _public_methods_ = [ 'SplitString' ] _reg_progid_ = "PythonDemos.Utilities" # NEVER copy the following ID # Use"print pythoncom.CreateGuid()" to make a new one. _reg_clsid_ = pythoncom.CreateGuid() print _reg_clsid_ def SplitString(self, val, item=None): import string if item != None: item = str(item) return string.split(str(val), item) # Add code so that when this script is run by # Python.exe,.it self-registers. if __name__=='__main__': print 'Registering Com Server' import win32com.server.register win32com.server.register.UseCommandLine(PythonUtilities) // the C# code using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Type pythonServer; object pythonObject; pythonServer = Type.GetTypeFromProgID("PythonDemos.Utilities"); pythonObject = Activator.CreateInstance(pythonServer); } } } ```