2016-12-14 10 views
0

Я следовал шаги, описанные в этом вопросе:Невозможно загрузить .NET DLL из рубина

Can Ruby import a .NET dll?

И так, у меня есть это в C# код:

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

Под раствором name: RubyToCSharp

Я проверил Register for COM interop на VS и создал следующий рубиновый код:

require "win32ole" 

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

А теперь я пытался запустить этот рубин из Powershell и я постоянно получаю эту ошибку:

./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>' 

Любые мысли о том, что я пропавших без вести здесь?

EDIT

После проверки, если мой длл был регистр в соответствии с this SO question, кажется, что на самом деле моя длл зарегистрирован, но до сих пор, то же самое происходит ошибка.

Действительно запутался здесь ...

ответ

1

только классы, которые отмечены ComVisible будут экспортированы в соответствующие ключи во время регистрации. Также очень, очень хорошая идея (я бы сказал, обязательная) иметь атрибут Guid вместо того, чтобы принимать значение по умолчанию, которое может меняться во время каждой компиляции. У вас также может быть свой собственный атрибут ProgId, но часто по умолчанию для Namespace.ClassName достаточно (где пространство имен - это пространство имен, в котором находится ваш класс, а ClassName - это имя вашего класса).

Попробуйте это:

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

Вот что я вижу со стороны .NET. У меня нет опыта работы с Ruby.

Это также поможет, если ваш Ruby-процесс 32-разрядный. VIsual Studio обычно регистрирует только класс с 32-разрядной системой времени выполнения на 64-битных операционных системах.

Для автономной регистрации за пределами IDE, использовать что-то вроде:

regasm.exe /tlb /codebase YourDll.dll 

Убедитесь, что вы используете Regasm.exe для правильного выполнения .NET и правильной 32/64-битным вкус.

Если ваша DLL зарегистрирована правильно с помощью COM, она должна быть вызвана через VBScript. Сделать простой VBScript под названием test.vbs:

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

Если вы дважды щелкните по имени файла в проводнике или просто введите test.vbs из командной строки оболочки он будет пытаться запустить программу VBS с wscript.exe в C: \ WINDOWS \ system32 \ wScript.exe.

Вероятно, это произойдет с 64-разрядной ОС, поскольку по умолчанию VS только регистрирует сборку .NET для COM с 32-разрядной подсистемой.Для того, чтобы попытаться запустить его на 32-битной подсистеме, попробуйте:

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

Если какой-либо из этих методов не удается, то ваша DLL не зарегистрирована правильно.

+0

Спасибо за ответ joe, Пара вещей: 1) [сборка: ComVisible (false)] может быть в файле AssemblyInfo.cs и сделает все классы com видимыми (у меня это настроено) в моем проекте. 2) Мне нужно понять, если он зарегистрирован через VS15, означает ли это, что эта DLL доступна через всю ОС? или он «жив» только в VS15-гире? – Itzik984

+0

Записи в реестре, необходимые для COM, будут отображаться на всей ОС, предполагая, что вы запускаете VS как повышенный администратор. Быстрый трюк, чтобы проверить, если он работает, чтобы написать VBS скрипт: 'Dim obj' ' установить OBJ = CreateObject ("ComLIb.LogWriter") '' MsgBox TypeName (объект) ' Возникают проблемы ... Выполнить это с помощью C: \ Windows \ system32 \ wScript.exe и запустить его с помощью C: \ Windows \ SysWOW64 \ wscript.exe по умолчанию он должен добиться успеха с одним в каталоге SysWow64 , Это скажет вам, правильно ли зарегистрирована. –

+0

Хорошо, еще раз спасибо ... Все еще не знаю, что здесь происходит. похоже, что я все делаю, как должен. – Itzik984

0

Решено, что может показаться довольно странным решением.

Изменено это:

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

Для этого:

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

И все работало.