2009-06-28 1 views
5

Ich wollte Python-com-Server mit Win32com-Erweiterungen zu implementieren. Dann verbrauchen Sie den Server aus dem .NET. Ich habe das folgende Beispiel verwendet, um den COM-Server zu implementieren, und es läuft ohne ein Problem, aber wenn ich versuche, es mit C# zu verbrauchen, bekam ich FileNotFoundException mit der folgenden Nachricht "Abrufen der COM-Klasse Factory für Komponente mit CLSID {676E38A6-7FA7-4BFF- 9179-AE959734DEBB} fehlgeschlagen aufgrund des folgenden Fehlers: 8007007e. " . Ich postete auch den C# -Code. Ich frage mich, ob ich etwas vermisse, würde ich jede Hilfe schätzen.Python-COM-Server von .NET verwenden

Danke, 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

Beachten Sie die Warnung im Python-Code, nicht bei jedem Aufruf eine neue GUID zu verwenden. Erstellen Sie eine GUID nur einmal. – gimel

+0

Der von Ihnen gepostete Code dient zum Registrieren eines COM-Servers. Haben Sie auch den eigentlichen Server implementiert (und ausgeführt)? –

+0

Ich dachte, die Registrierung des Servers bedeutet, dass es läuft. Kannst du mir mehr Führer geben? danke – Sarah

Antwort

10

Ein COM-Server ist nur ein Teil der Software (eine DLL oder eine ausführbare Datei), die Remote Procedure Calls (RPC) über ein definiertes Protokoll akzeptiert. Ein Teil des Protokolls besagt, dass der Server eine eindeutige ID haben muss, die in der Windows-Registrierung gespeichert wird. In unserem Fall bedeutet dies, dass Sie einen Server "registriert" haben, der nicht existiert. Also der Fehler (Komponente nicht gefunden).

So soll es so etwas wie diese (wie üblich, ist dies nicht getesteten 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'] 

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

Dann sollen Sie von der Kommandozeile ausgeführt werden (vorausgesetzt, dass das Skript HelloWorldCOM.py genannt):

HelloWorldCOM.py --register 
HelloWorldCOM.py

Klasse HelloWorld ist die eigentliche Implementierung des Servers. Es gibt eine Methode (Hello) und eine Reihe von Attributen frei, von denen eines schreibgeschützt ist. Mit dem ersten Befehl registrieren Sie den Server; Mit dem zweiten starten Sie es und dann steht es anderen Anwendungen zur Verfügung.

+0

um den vorherigen Code ohne Fehler auszuführen, rief ich die Methode localserver.main() anstelle von localserver.serve ('B83DD222-7750-413D-A9AD-01B37021B24B'). Ich habe den Server gestartet und gebe ihm das _reg_progid_ als Argument. – Sarah

+1

'localserver.serve ('B83DD222-7750-413D-A9AD-01B37021B24B')' ist fast richtig. Sie müssen die geschweiften Klammern einfügen und in eine Liste einfügen: 'localserver.serve (['{B83DD222-7750-413D-A9AD-01B37021B24B}'])'. Funktioniert ansonsten einwandfrei. –

+0

Kann ich es ohne Registrierung ausführen? Siehe meine Frage.:http://stackoverflow.com/questions/41975659/portable-python-c-server-using-pywin32 – Rahul

0

Sie benötigen Process Monitor auf Ihrem C# Executable führen Sie die Datei auf die Spur, die nicht gefunden wird.