从.NET消费Python COM服务器

6 投票
2 回答
5908 浏览
提问于 2025-04-15 12:32

我想用win32com扩展来实现一个Python的COM服务器。然后我想在.NET中使用这个服务器。我参考了一个示例来实现这个COM服务器,运行得很顺利。但是当我尝试用C#来调用它时,出现了FileNotFoundException的错误,错误信息是“检索组件的COM类工厂时出错,CLSID为{676E38A6-7FA7-4BFF-9179-AE959734DEBB},错误代码:8007007e。”我也把C#的代码贴出来了。我在想是不是漏掉了什么,任何帮助都非常感谢。

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

        }
    }
}

2 个回答

0

你需要在你的C#程序上运行进程监视器,这样可以帮助你找到那个找不到的文件。

12

COM服务器其实就是一段软件(可以是一个DLL文件或者一个可执行文件),它可以通过一种特定的协议来接受远程过程调用(RPC)。这个协议的一部分要求服务器必须有一个唯一的ID,这个ID会存储在Windows的注册表里。

在我们的例子中,这意味着你注册了一个并不存在的服务器。所以就出现了错误(找不到组件)。

所以,应该像这样做(不过这段代码没有经过测试!):

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}'])

然后你需要在命令行中运行(假设这个脚本叫做HelloWorldCOM.py):

HelloWorldCOM.py --register
HelloWorldCOM.py

类HelloWorld就是服务器的实际实现。它提供了一个方法(Hello)和几个属性,其中有一个是只读的。

用第一条命令,你注册了这个服务器;用第二条命令,你运行它,这样其他应用程序就可以使用它了。

撰写回答