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

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

问题描述

我遇到了一种情况,我正在创建一个使用另一个第三方 DLL 的 DLL,但我更希望能够将第三方 DLL 构建到我的 DLL 中,而不必将它们放在一起,如果可能.

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.

这是 C# 和 .NET 3.5.

This with is C# and .NET 3.5.

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

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.

我最初计划这样做的方式是编写代码将第三方 DLL 放在 System.Reflection.Assembly.GetExecutingAssembly().Location.ToString() 指定的位置减去最后一个 /nameOfMyAssembly.dll.我可以在这个位置成功保存第三方 .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 SettingsmyUserNameLocal SettingsApplication数据组装dl3KXPPAX6Y.ZCYA1MZ1499.1TRe0115d4491bb86eb_fe18c901

C:Documents and SettingsmyUserNameLocal SettingsApplication Dataassemblydl3KXPPAX6Y.ZCYA1MZ1499.1TRe0115d4491bb86eb_fe18c901

),但是当我到达需要此 DLL 的代码部分时,它找不到它.

), 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?

推荐答案

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

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

其中 StreamToBytes 可以定义为:

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

最后,正如一些人已经提到的,ILMerge 可能是另一种选择考虑一下,尽管涉及更多.

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

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

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