using registered com object dll from .NET
Question
I implemented a python com server and generate an executable and dll using py2exe tool. then I used regsvr32.exe to register the dll.I got a message that the registration was successful. Then I tried to add reference to that dll in .NET. I browsed to the dll location and select it, but I got an error message box that says: A reference to the dll could not be added, please make sure that the file is accessible and that it is a valid assembly or COM component.The code of the server and setup script is added below. I want to mention that I can run the server as a python script and consume it from .net using late binding. Is there something I'm missing or doing wrong? I would appreciate any help.
thanks, Sarah
hello.py
import pythoncom
import sys
class HelloWorld:
#pythoncom.frozen = 1
if hasattr(sys, 'importers'):
_reg_class_spec_ = "__main__.HelloWorld"
_reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
_reg_clsid_ = pythoncom.CreateGuid()
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestServer"
_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
print "Hello" + " " * self.softspace + str(who)
return "Hello" + " " * self.softspace + str(who)
if __name__=='__main__':
import sys
if hasattr(sys, 'importers'):
# running as packed executable.
if '--register' in sys.argv[1:] or '--unregister' in sys.argv[1:]:
# --register and --unregister work as usual
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
else:
# start the server.
from win32com.server import localserver
localserver.main()
else:
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
setup.py
from distutils.core import setup
import py2exe
setup(com_server = ["hello"])
Solution 2
I will answer my question to help any one may have similar questions. I hope that would help. I can not find my server on the COM tab because, .NET (& Visual-Studio) need COM servers with TLB. But Python's COM servers have no TLB. So to use the server from .NET by (C# and Late binding). The following code shows how to make this:
// 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);
}
}
} `
OTHER TIPS
The line:
_reg_clsid_ = pythoncom.CreateGuid()
creates a new GUID everytime this file is called. You can create a GUID on the command line:
C:\>python -c "import pythoncom; print pythoncom.CreateGuid()"
{C86B66C2-408E-46EA-845E-71626F94D965}
and then change your line:
_reg_clsid_ = "{C86B66C2-408E-46EA-845E-71626F94D965}"
After making this change, I was able to run your code and test it with the following VBScript:
Set obj = CreateObject("Python.TestServer")
MsgBox obj.Hello("foo")
I don't have MSVC handy to see if this fixes the "add reference" problem.
If you want to use a registered Com object, you need to find it on the Com tab in the Add Reference dialog box. You do not navigate to the dll.