2016-12-14 4 views
0

ich die in dieser Frage beschriebenen Schritte befolgt haben:Kann laden .NET nicht von Ruby dll

Can Ruby import a .NET dll?

Und so, ich habe diese C# -Code:

using System; 
using System.IO; 

namespace ComLib 
{ 
    public class LogWriter 
    { 
     public void WriteLine(string line) 
     { 
      using (var log = new StreamWriter(File.OpenWrite(@"c:\log.file"))) 
      { 
       log.WriteLine(line); 
      } 
     } 
    } 
} 

Unter einer Lösung genannt: den folgenden ruby-Code RubyToCSharp

überprüfte ich die Register for COM interop in VS und erstellt:

require "win32ole" 

lib = WIN32OLE.new('RubyToCSharp.ComLib.LogWriter') 
lib.WriteLine('calling .net from ruby via COM, hooray!') 

Und jetzt habe ich versucht, diesen Rubin von Powershell zu laufen und ich erhalte immer diese Fehlermeldung:

./exmpl.rb:4:in `initialize': unknown OLE server: `RubyToCSharp.ComLib.LogWriter' (WIN32OLERuntimeError) 
    HRESULT error code:0x800401f3 
     Invalid class string 
     from ./exmpl.rb:4:in `new' 
     from ./exmpl.rb:4:in `<main>' 

Irgendwelche Gedanken auf, was ich hier bin verpasst?

EDIT

Nach der Überprüfung, ob meine dll-Register war this SO question nach, Es scheint, dass in der Tat ist meine dll registriert, aber immer noch, geschieht der gleiche Fehler.

wirklich verwirrt hier ...

Antwort

1

Nur Klassen, die ComVisible sind markiert, werden den entsprechenden Schlüssel bei der Registrierung exportiert werden. Es ist auch eine sehr, sehr gute Idee (ich würde sagen, obligatorisch), ein Guid-Attribut zu haben, anstatt den Standardwert zu übernehmen, der sich bei jeder Kompilierung ändern kann. Sie können auch Ihr eigenes ProgId-Attribut haben, aber oft genügt der Standardwert von Namespace.ClassName (wobei Namespace der Namespace ist, in dem sich Ihre Klasse befindet, und ClassName der Name Ihrer Klasse).

Try this:

using System; 
using System.IO; 
using System.Runtime.InteropServices; 

namespace ComLib 
{ 
    [ComVisible(true)] // needs to be marked ComVisible 
    [Guid("ad4c28c9-4612-4ac3-8ca4-04a343f4f2b9")] // generate your own 
    public class LogWriter 
    { 
     public void WriteLine(string line) 
     { 
      using (var log = new StreamWriter(File.OpenWrite(@"c:\log.file"))) 
      { 
       log.WriteLine(line); 
      } 
     } 
    } 
} 

Das ist, was ich von der .NET-Seite zu sehen. Ich habe keine Erfahrung mit dem Versuch, von Ruby zu konsumieren.

Es hilft auch, wenn Ihr Ruby-Prozess 32-Bit ist. Normalerweise registriert VIsual Studio die Klasse nur mit dem 32-Bit-Laufzeitsystem auf 64-Bit-Betriebssystemen.

Für Standalone-Registrierung außerhalb des IDE, verwenden Sie so etwas wie:

regasm.exe /tlb /codebase YourDll.dll 

Stellen Sie sicher, dass den regasm.exe für den richtigen .NET-Runtime verwenden und korrekten 32/64-Bit-Geschmack.

Wenn Ihre DLL korrekt mit COM registriert ist, sollte sie über VBScript aufrufbar sein. Stellen Sie eine einfache VBScript genannt Test.vbs:

Dim obj 
set obj = CreateObject("ComLib.LogWriter") 
MsgBox TypeName(obj) 

Wenn Sie einen Doppelklick auf den Dateinamen, im Explorer oder geben Sie einfach test.vbs von der Kommandozeilen-Shell wird es versuchen, das VBS-Programm mit wscript.exe zulaufen c: \ windows \ system32 \ wscript.exe.

Es wird wahrscheinlich auf einem 64-Bit-Betriebssystem fehlschlagen, weil VS standardmäßig nur die .NET-Assembly für COM mit dem 32-Bit-Subsystem registriert.Um zu versuchen, es auf den 32-Bit-Subsystem zu laufen, versuchen:

c:\windows\syswow64\wscript.exe test.vbs 

Wenn eine dieser beiden Methoden fehlschlägt, dann Ihre DLL nicht korrekt registriert ist.

+0

Danke für die Antwort Joe, Paar der Dinge: 1) [Assembly: ComVisible (false)] könnte in der Datei AssemblyInfo.cs und werden alle Klassen com sichtbar (ich habe dies konfiguriert) bei meinem Projekt. 2) Ich muss verstehen, wenn es über VS15 registriert ist, bedeutet dies, dass diese DLL über das gesamte Betriebssystem verfügbar ist? oder ist es nur im VS15 dir "lebendig"? – Itzik984

+0

Die Einträge in der Registrierung, die für COM erforderlich sind, werden im gesamten Betriebssystem vorausgesetzt, dass Sie VS als einen erhöhten Administrator ausführen. Ein schneller Trick zu testen, ob es funktioniert, ist ein VBS-Skript zu schreiben: 'Dim obj' ' set obj = Create ("ComLIb.LogWriter") '' MsgBox Type-Name (obj) ' Haben sie Probleme beim ... Run es über c: \ windows \ system32 \ wscript.exe und über c: \ windows \ SysWow64 \ wscript.exe standardmäßig sollte es mit dem in der SysWow64 Verzeichnis erfolgreich . Dieser wird Ihnen sagen, ob er korrekt registriert wurde. –

+0

Ok, danke nochmal ... Habe immer noch keine Ahnung, was hier schief läuft. scheint, dass ich alles so mache, wie ich sollte. – Itzik984

0

Gelöst, in was könnte eine ziemlich seltsame Lösung sein.

dies geändert:

lib = WIN32OLE.new('RubyToCSharp.ComLib.LogWriter') 

Um dies:

lib = WIN32OLE.new('ComLib.LogWriter') 

Und alles funktionierte.