Использование COM-сервера Python из .NET

Я хотел реализовать com-сервер python, используя расширения win32com. Затем используйте сервер из .NET. Я использовал следующий пример для реализации COM-сервера, и он работает без проблем, но когда я пытаюсь использовать его с помощью C #, я получаю FileNotFoundException со следующим сообщением «Получение фабрики классов COM для компонента с CLSID {676E38A6-7FA7-4BFF-9179». -AE959734DEBB} не удалось из-за следующей ошибки: 8007007e." . Я также разместил код С#. Интересно, если я что-то упустил, я был бы признателен за любую помощь.

Спасибо, Сара

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

        }
    }
}

person Sarah    schedule 28.06.2009    source источник
comment
Обратите внимание на предупреждение в коде Python, чтобы не использовать новый GUID при каждом вызове. Создайте GUID только один раз.   -  person gimel    schedule 28.06.2009
comment
Код, который вы разместили, предназначен для регистрации COM-сервера; Вы также внедрили (и работаете) реальный сервер?   -  person rob    schedule 28.06.2009
comment
Я думал, что регистрация сервера означает, что он работает. Можете ли вы дать мне больше руководств. Благодарность   -  person Sarah    schedule 28.06.2009


Ответы (2)


COM-сервер — это просто часть программного обеспечения (DLL или исполняемый файл), которое будет принимать удаленные вызовы процедур (RPC) через определенный протокол. В части протокола говорится, что сервер должен иметь уникальный идентификатор, хранящийся в реестре 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) и пару атрибутов, один из которых доступен только для чтения. Первой командой вы регистрируете сервер; со вторым вы запускаете его, и тогда он становится доступным для использования из других приложений.

person rob    schedule 28.06.2009
comment
чтобы запустить предыдущий код без ошибок, я вызвал метод localserver.main() вместо localserver.serve('B83DD222-7750-413D-A9AD-01B37021B24B'). Я запустил сервер и передал ему reg_progid в качестве аргумента. - person Sarah; 02.07.2009
comment
localserver.serve('B83DD222-7750-413D-A9AD-01B37021B24B') почти правильно. Вам нужно включить фигурные скобки и поместить его в список: localserver.serve(['{B83DD222-7750-413D-A9AD-01B37021B24B}']). В остальном работает безотказно. - person Endre Both; 22.03.2015
comment
Можно ли запустить без регистрации? см. мой вопрос.: stackoverflow.com/questions /41975659/ - person Rahul; 01.02.2017
comment
Тем, кто использует Python 3.7 (и новейшую версию PyWin32), необходимо добавить переменные: _reg_verprogid_ и _reg_class_spec_. Первый примерно такой же, как _reg_progid_ (например, Python.TestServer.2), второй должен быть ‹filename›.‹classname› (как модуль Python). - person KilZone; 20.07.2018
comment
Как изящно остановить работающий сервер localserver.serve([{clsid}])? @EndreBoth - person Krishna Kumar; 03.05.2021
comment
Кроме того, как я могу получить доступ к методу Hello непосредственно в Excel с помощью функции RTD? @EndreBoth, например, я не могу получить какое-либо значение в excel для =RTD("Python.TestServer","","Hello","Jack") - person Krishna Kumar; 03.05.2021

Вам нужно запустить Process Monitor в исполняемом файле C#, чтобы отследить файл что не найдено.

person Shay Erlichmen    schedule 28.06.2009