6

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

        }
    }
}
3
  • 2
    Note warning in the python code, not to use a new GUID on every call. Create a GUID only once. Commented Jun 28, 2009 at 12:53
  • The code you posted is for registering a COM server; do you also have implemented (and running) the actual server? Commented Jun 28, 2009 at 13:26
  • I thought registering the server means it is running. Can you give me more guides. thanks Commented Jun 28, 2009 at 13:31

2 Answers 2

12

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.

Sign up to request clarification or add additional context in comments.

6 Comments

in order to run the previous code without error, I called the method localserver.main() instead of localserver.serve('B83DD222-7750-413D-A9AD-01B37021B24B'). I started the server and give it the reg_progid as an argument.
localserver.serve('B83DD222-7750-413D-A9AD-01B37021B24B') is almost correct. You need to include the braces and put it in a list: localserver.serve(['{B83DD222-7750-413D-A9AD-01B37021B24B}']). Works flawlessly otherwise.
Is it possible to run it without registering? see my question.:stackoverflow.com/questions/41975659/…
Those using Python 3.7 (and newest version of PyWin32), you need to add variables: _reg_verprogid_ and _reg_class_spec_. The first one is about the same as _reg_progid_ (for example Python.TestServer.2), the second should be <filename>.<classname> (like a Python module).
How to stop the running server localserver.serve([{clsid}]) gracefully ? @EndreBoth
|
0

You need run Process Monitor on your C# Executable to track down the file that is not found.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.