将一个dll嵌入另一个作为嵌入式资源,然后从我的代码中调用它 [英] Embedding one dll inside another as an embedded resource and then calling it from my code

查看:879
本文介绍了将一个dll嵌入另一个作为嵌入式资源,然后从我的代码中调用它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个情况,我有一个DLL,我创建使用另一个第三方DLL,但我宁愿能够构建第三方DLL到我的DLL,而不必将它们保持在一起,如果



这是C#和.NET 3.5。



我想这样做的方式是通过将第三方DLL作为嵌入式资源存储,然后在第一个DLL的执行期间将其放置在适当的位置。



我原本打算这样做的方式是编写代码将第三方DLL放在System.Reflection.Assembly.GetExecutingAssembly()指定的位置。Location.ToString()减去最后一个/nameOfMyAssembly.dll。我可以成功保存第三方.DLL在这个位置(最后是(C:\Documents and Settings\myUserName\Local Settings\Application Data\assembly\dl3\KXPPAX6Y.ZCY\A1MZ1499 .1TR\e0115d44\91bb86eb_fe18c901),但是当我到我的代码的一部分需要这个DLL它找不到它。



有人有任何想法关于我需要做的不同?

解决方案

将第三方程序集嵌入资源后,添加代码以订阅 AppDomain.AssemblyResolve 在应用程序启动期间当前域的事件当CLR的Fusion子系统根据实际的探测(策略)找不到程序集时,会触发此事件。 AppDomain.AssemblyResolve 的事件处理程序,加载资源ce使用 Assembly.GetManifestResourceStream ,并将其内容作为字节数组提供到相应的 Assembly.Load 重载。以下是C#中的一个这样的实现方式:

  AppDomain.CurrentDomain.AssemblyResolve + =(sender,args)=> ; 
{
var resName = args.Name +.dll;
var thisAssembly = Assembly.GetExecutingAssembly();
使用(var input = thisAssembly.GetManifestResourceStream(resName))
{
return input!= null
? Assembly.Load(StreamToBytes(input))
:null;
}
};

其中 StreamToBytes 可以定义为: / p>

 静态字节[] StreamToBytes(流输入)
{
var capacity = input.CanSeek? (int)input.Length:0;
using(var output = new MemoryStream(capacity))
{
int readLength;
var buffer = new byte [4096];

do
{
readLength = input.Read(buffer,0,buffer.Length);
output.Write(buffer,0,readLength);
}
while(readLength!= 0);

return output.ToArray();
}
}

最后,有几个已经提到, ILMerge 可能是另一个可以考虑的选择,尽管有更多的参与。


I've got a situation where I have a DLL I'm creating that uses another third party DLL, but I would prefer to be able to build the third party DLL into my DLL instead of having to keep them both together if possible.

This with is C# and .NET 3.5.

The way I would like to do this is by storing the third party DLL as an embedded resource which I then place in the appropriate place during execution of the first DLL.

The way I originally planned to do this is by writing code to put the third party DLL in the location specified by System.Reflection.Assembly.GetExecutingAssembly().Location.ToString() minus the last /nameOfMyAssembly.dll. I can successfully save the third party .DLL in this location (which ends up being (C:\Documents and Settings\myUserName\Local Settings\Application Data\assembly\dl3\KXPPAX6Y.ZCY\A1MZ1499.1TR\e0115d44\91bb86eb_fe18c901) , but when I get to the part of my code requiring this DLL it can't find it.

Does anybody have any idea as to what I need to be doing differently?

解决方案

Once you've embedded the third-party assembly as a resource, add code to subscribe to the AppDomain.AssemblyResolve event of the current domain during application start-up. This event fires whenever the Fusion sub-system of the CLR fails to locate an assembly according to the probing (policies) in effect. In the event handler for AppDomain.AssemblyResolve, load the resource using Assembly.GetManifestResourceStream and feed its content as a byte array into the corresponding Assembly.Load overload. Below is how one such implementation could look like in C#:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    var resName = args.Name + ".dll";    
    var thisAssembly = Assembly.GetExecutingAssembly();    
    using (var input = thisAssembly.GetManifestResourceStream(resName))
    {
        return input != null 
             ? Assembly.Load(StreamToBytes(input))
             : null;
    }
};

where StreamToBytes could be defined as:

static byte[] StreamToBytes(Stream input) 
{
    var capacity = input.CanSeek ? (int) input.Length : 0;
    using (var output = new MemoryStream(capacity))
    {
        int readLength;
        var buffer = new byte[4096];

        do
        {
            readLength = input.Read(buffer, 0, buffer.Length);
            output.Write(buffer, 0, readLength);
        }
        while (readLength != 0);

        return output.ToArray();
    }
}

Finally, as a few have already mentioned, ILMerge may be another option to consider, albeit somewhat more involved.

这篇关于将一个dll嵌入另一个作为嵌入式资源,然后从我的代码中调用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆