我有一个C#项目,其中嵌入了一个IronRuby程序。该项目(包括我的ruby脚本)被编译为Visual Studio 2010中的.exe文件以进行分发。我正在使用与此类似的模式来引导IronRuby脚本:http://pastebin.com/NKes1cyc(和Jimmy Schementi在此处详细介绍:http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html)。
我的问题:我想在我的C#程序集中嵌入一个gem(json_pure)并从ruby脚本中调用它。
我发现了一些资源:
在JRuby中,您可以轻松地将gem打包到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标准库的同时将Ruby编译成.exe(我认为它动态创建并编译C#项目)。但看起来它只是嵌入了预先构建的IronRuby .dll,而不是ruby .rb文件。如果我能弄清楚如何将Ruby源文件编译成.dll,那么这个工具使用的方法就可以了。
如何将IronRuby gem嵌入到C#程序集中(或将IronRuby gem编译为.dll)?
编辑:
IronRuby In Action (“使用外部库”)的第472页解释了如何从嵌入式ruby文件中要求标准的ruby库。它涉及将文件夹添加到运行时搜索路径集合中,如下所示(为简洁起见而编辑):
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,但我想将ruby文件(从gem中)嵌入到程序集中,这样就可以在没有预装IronRuby的情况下运行它。
编辑2(进一步研究):
通过上面引用的irpack工具的源代码,我注意到Kumaryu通过System.IO.Packaging.Package类将资源嵌入到最终的程序集中,然后将包传递给对msbuild的调用(参见{ {3}})。也许对将文件打包成可执行文件的进一步研究将导致解决方案。我看到的问题是gem require
其他ruby文件中的ruby文件...汇编包中的ruby文件require
在同一个包中的其他ruby文件中?
编辑3:
我还没有得到任何答案,但我有兴趣听到任何人的反馈,即使这只是一个关于在哪里看的链接或建议。我是msbuild的新手,而且文档非常庞大。对“msbuild embed zip package”的初步网络搜索没有透露任何相关内容。
答案 0 :(得分:3)
Require is a method可以像任何其他ruby方法一样被覆盖。我认为这就是原始的ruby gems包的工作原理,gems会简单地覆盖require
。
如果您可以以某种方式将gem打包到.exe中,则可以覆盖require
以从程序集加载。
答案 1 :(得分:3)
试试这个https://github.com/rifraf/IronRubyAppPackager#readme(或者等我报告它是否适用于我想要嵌入的库)
报告回来:
我去过的过程是......
从https://github.com/rifraf分叉和子模块化所有项目(IronRubyEmbeddedApps,IronRubyAppPackager,Serfs和Vendorize),并将它们全部添加到VS解决方案中。我将所有项目更新为.NET4并使它们相互引用,而不是包含.net2程序集
执行Vendorize以通过运行来翻录所有依赖项/ gems 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
生成一个c#项目
D:\projects\SomeLibrary\lib>ruby -I..\..\IronRubyAppPackager\lib\IRPackager.rb some_lib.rb
将some_lib.csproj添加到我的解决方案中,将其升级为.net4并修复了引用
var Ruby = new EmbeddedRuby(); Ruby.Decoder = new Program.GZipDecoder(); Ruby.Mount("App"); Ruby.Run("gocardless.rb");
它成功了!我以为很棒!
实际上,此时我发现它在步骤2中未能将每个所需的库供应商。 Vendorize通过拦截require
个调用,然后将被调用的rb文件保存到_Vendor_
- 如果require
未执行(因此运行所有测试并希望测试覆盖率为100%)来赢得工作不被接受。
出于某种原因,即使有需要,它也没有获取所需的文件之一。最后,我通过复制我的库并使用bundle install --deployment
命令手动创建了 vendor 目录的内容。重复步骤3和4,我完成了......对吗?
没有,当我运行生成的项目时,我得到一些关于no such file to load -- json/pure
的错误 - 我认为这是做一个没有本地json实现的ironruby,我做手动供应和我不得不躲避的组合今天在几个方面的事情。
总而言之 - 如果您的库及其依赖项正确地与ironruby一起工作,这种方法非常有效,并且您可以使供应商正常工作。
我放弃并以旧式的方式将库移植到c#。
编辑:如下所述,rifraf帮助我并研究更新我正在使用的工具。看t(他的)空间!
答案 2 :(得分:3)
我正在使用https://stackoverflow.com/users/2086/mcintyre321使用我的打包代码(https://github.com/rifraf/IronRubyAppPackager#readme)将他的库包装到C#/ IronRuby中。
供应商化步骤中需要一些修复程序,这些修复程序与嵌入了RubyGems而不是加载的Ruby的更高版本相关,但是正在取得进展。
他的代码需要'json',我有一个技巧来强制它使用Ruby实现而不是C-linkage .so文件。这应该意味着它可以与IronRuby一起使用。将报告回来,或者随时与我联系您想要运行的来源。