Как вставить рубиновый камень в проект С# и потребовать его от встроенного IronRuby script? - программирование
Подтвердить что ты не робот

Как вставить рубиновый камень в проект С# и потребовать его от встроенного IronRuby script?

У меня есть проект С#, в который я встроил программу IronRuby. Проект (включая мой ruby ​​ script) скомпилирован в файл .exe в Visual Studio 2010 для распространения. Я использую шаблон, подобный этому для начальной загрузки IronRuby script: http://pastebin.com/NKes1cyc (и Джимми Schementi более подробно описывает здесь: http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html).

Моя проблема: я хотел бы встроить gem (json_pure) в свою сборку С# и вызвать его из ruby ​​ script.

Некоторые ресурсы, которые я нашел:

  • В JRuby вы можете легко упаковать драгоценный камень в файл jar, а затем просто потребовать файл jar во время выполнения - http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar

  • Инструмент irpack (http://github.com/kumaryu/irpack) способен скомпилировать Ruby в .exe(я думаю, что он динамически создает и компилирует проект С#) при встраивании стандартной библиотеки ruby. Но похоже, что это только встраивание готовых файлов IronRuby.dlls, а не ruby ​​.rb. Подход, который использует этот инструмент, будет работать, если я смогу выяснить, как скомпилировать исходные файлы Ruby в .dll.

Как встроить жемчужину IronRuby в сборку С# (или скомпилировать жемчужину IronRuby в .dll)?

EDIT:

Страница 472 IronRuby In Action ( "Использование внешних библиотек" ) объясняет, как требовать стандартных рубиновых библиотек из встроенного рубинового файла. Это связано с добавлением папки (ов) в коллекцию путей поиска во время выполнения, следующим образом (отредактировано для краткости и ясности):

ScriptEngine engine = IronRuby.Ruby.CreateEngine();
var searchPaths = engine.GetSearchPaths().Concat(new[] 
{
    "C:\\Program Files (x86)\\IronRuby 1.1\\Lib\\ruby\\1.9.1",
    "C:\\Program Files (x86)\\IronRuby 1.1\\Lib\\ironruby"
});
engine.SetSearchPaths(searchPaths)

Этот подход предполагает, что на хост-машине установлен IronRuby, но я хочу вставить рубиновые файлы (из жемчужины) в сборку, чтобы он мог запускаться без предварительной установки IronRuby.

EDIT 2 (дальнейшие исследования):

Чтение исходного кода инструмента irpack, упомянутого выше, я замечаю, что Kumaryu внедряет ресурсы в финальную сборку через класс System.IO.Packaging.Package, а затем передает пакет в вызов msbuild (см. https://github.com/kumaryu/irpack/blob/master/lib/irpack/packager.rb). Возможно, некоторые дальнейшие исследования по упаковыванию файлов в исполняемый файл приведут к решению. Проблема, которую я вижу, в том, что рубиновые файлы в gem require других рубиновых файлах... может ли рубиновый файл в сборке require других рубиновых файлов в одном пакете?

ИЗМЕНИТЬ 3:

Я еще не получил ответа на этот вопрос, но мне было бы интересно услышать любую обратную связь, даже если это просто ссылка или предложение о том, где искать. Я новичок в msbuild, и документация довольно здоров. Первоначальный веб-поиск "msbuild embed zip package" не выявил ничего значимого.

4b9b3361

Ответ 1

Требовать - это метод, который можно переопределить, как любой другой метод ruby. Я думаю, что именно так работал оригинальный пакет рубиновых драгоценных камней, драгоценные камни просто переопределили require.

Если вы можете каким-то образом упаковать драгоценный камень в ваш .exe, вы можете переопределить require для загрузки из сборки.

Ответ 2

попробуйте https://github.com/rifraf/IronRubyAppPackager#readme (или дождитесь, пока я отчитаюсь о том, работает ли он с библиотекой, которую я пытаюсь встроить)

Отчетность:

Процесс, к которому я пошел, - это...

  • fork и подмодуль всех проектов (IronRubyEmbeddedApps, IronRubyAppPackager, Serfs and Vendorize) из https://github.com/rifraf и добавили их все в решение VS. Я обновил все проекты до .NET4 и сделал их ссылкой друг на друга, а не включенные сборки .net2

  • выполнил команду Vendorize для копирования всех зависимостей/драгоценных камней D:\projects\SomeLibrary\lib_vendor_ путем запуска:

    D:\projects\SomeLibrary\lib>ruby -I..\..\Vendorize\lib -rvendorize some_lib.rb

  • Сгенерировал проект С# в D:\projects\SomeLibrary\lib\_IRPackager_\some_lib.csproj, выполнив:

    D:\projects\SomeLibrary\lib>ruby -I..\..\IronRubyAppPackager\lib\IRPackager.rb some_lib.rb

  • Добавил some_lib.csproj к моему решению, обновил его до .net4 и фиксированных ссылок

  • На этом этапе вы можете запустить проект в .NET, автономно, выполнив
var Ruby = new EmbeddedRuby();
Ruby.Decoder = new Program.GZipDecoder();
Ruby.Mount("App");
Ruby.Run("gocardless.rb");

И это сработало! Блестящий я думал!

На самом деле в этот момент я обнаружил, что он не выполнил шаг 2 для Vendorize каждой отдельной требуемой библиотеки. Vendorize работает, перехватывая вызовы require, а затем сохраняя вызываемые rb файлы на _Vendor_ - если require не выполняется (поэтому для запуска всех тестов и покрытия тестирования надежда 100%) он не будет поднят.

По какой-то причине он не собирал один из необходимых файлов, хотя требовалось. В конце концов, я вручную создал контент для каталога поставщика, скопировав мою библиотеку и используя команду bundle install --deployment. Повторите шаги 3 и 4, и я закончу... правильно?

Нет, я получаю некоторую ошибку в no such file to load -- json/pure при запуске сгенерированного проекта - я думаю, что это что-то, что можно сделать с помощью комбинации ironruby, не имеющей встроенной json-реализации, я делаю ручную вендоризацию, и мне приходится делать вещи в сегодня несколько пунктов.

В заключение - этот метод очень почти работает, будет работать, если ваша библиотека и ее зависимости будут работать с ironruby должным образом, и вы можете заставить vendorize работать правильно.

Я сдаюсь и портирую библиотеку на С# старомодным способом.

edit: как упоминалось ниже, rifraf помогает мне и изучает обновляемые инструменты, которые я использовал. следите за его пространством!

Ответ 3

Я работаю с https://stackoverflow.com/users/2086/mcintyre321, чтобы получить его библиотеку, завернутую в С#/IronRuby, используя мой код упаковки (https://github.com/rifraf/IronRubyAppPackager#readme).

На этапе vendorize есть некоторые исправления, связанные с более поздними версиями Ruby с встроенным RubyGems, а не с загрузкой, но прогресс выполняется.

Его код требует "json", и у меня есть трюк, чтобы заставить его использовать реализацию Ruby, а не файлы Cso-link.so. Это должно означать, что он будет работать с IronRuby в порядке. Откроется отчет или не стесняйтесь обращаться ко мне с источником, который вы хотите запустить.