views:

209

answers:

3

Hi all,

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"])

A: 

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.

C. Ross
Thanks for answering, I did that at first but did not find my server in the Com tab, so I thought i would navigate to it.
Sarah
A: 

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.

ars
Thanks for your answer, I followed your guides I registered the server without problem. But I still can not find my server on COM Tab.
Sarah
I think you'll need to write and register a type library if you want the COM server to show up in that tab. I don't know if pythoncom can generate one, but you can do this by writing an IDL for your server and compiling it using MIDL.
ars
By the way, if you don't find your answer here, try the python-win32 list:http://mail.python.org/mailman/listinfo/python-win32That's a good place to get answers on python/win stuff.
ars
A: 

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);

    }
}

} `

Sarah