2009-06-28 16 views
5

Quería implementar el servidor python com utilizando las extensiones win32com. Luego consume el servidor desde .NET. Utilicé el siguiente ejemplo para implementar el servidor de com y se ejecuta sin problemas, pero cuando intento consumirlo usando C# obtuve FileNotFoundException con el siguiente mensaje "Recuperando la fábrica de la clase COM para el componente con CLSID {676E38A6-7FA7-4BFF- 9179-AE959734DEBB} falló debido al siguiente error: 8007007e ". . También publiqué el código C#. Me pregunto si me falta algo. Agradecería cualquier ayuda.Consumir el servidor COM Python desde .NET

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

     } 
    } 
} 
+1

Nota advertencia en el código python, no para utilizar un nuevo GUID en cada llamada. Crea un GUID solo una vez. – gimel

+0

El código que ha publicado es para registrar un servidor COM; ¿También has implementado (y ejecutado) el servidor real? –

+0

Pensé que registrar el servidor significa que se está ejecutando. ¿Me puedes dar más guías? gracias – Sarah

Respuesta

10

Un servidor COM es simplemente una pieza de software (un DLL o un ejecutable) que acepte llamadas a procedimiento remoto (RPC) a través de un protocolo definido. Parte del protocolo dice que el servidor debe tener una ID única, almacenada en el registro de Windows. En nuestro caso, esto significa que ha "registrado" un servidor que no existe. Por lo tanto, el error (componente no encontrado).

Por lo tanto, debería ser algo como esto (como de costumbre, se trata de código no probado!):

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

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

entonces usted debe ejecutar desde la línea de comandos (asumiendo que el script se llama HelloWorldCOM.py):

HelloWorldCOM.py --register 
HelloWorldCOM.py

Clase HelloWorld es la implementación real del servidor. Expone un método (Hola) y un par de atributos, uno de los dos es de solo lectura. Con el primer comando, registra el servidor; con el segundo, lo ejecuta y luego está disponible para su uso desde otras aplicaciones.

+0

para ejecutar el código anterior sin error, llamé al método localserver.main() en lugar de localserver.serve ('B83DD222-7750-413D-A9AD-01B37021B24B'). Inicié el servidor y le di el _reg_progid_ como argumento. – Sarah

+1

'localserver.serve ('B83DD222-7750-413D-A9AD-01B37021B24B')' es casi correcto. Debe incluir los paréntesis y ponerlo en una lista: 'localserver.serve (['{B83DD222-7750-413D-A9AD-01B37021B24B}'])'. Funciona impecablemente de lo contrario. –

+0

¿Es posible ejecutarlo sin registrarse? ver mi pregunta.http://stackoverflow.com/questions/41975659/portable-python-com-server-using-pywin32 – Rahul

0

Se necesitan ejecutar Process Monitor en su C# ejecutable para localizar el archivo que no se encuentra.

Cuestiones relacionadas