中嵌入一个dll中的另一个作为嵌入资源,然后从我的code调用它我的、资源、dll、code

2023-09-07 01:18:40 作者:傾聽初夏dē旋律

我有一个情况我有一个DLL,我创建使用其他第三方DLL,但我会preFER才能够建立,而不必让他们的第三方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.

就是我本来计划要做到这一点是通过编写code把第三方DLL由System.Reflection.Assembly.GetExecutingAssembly()指定的位置。Location.ToString()减去最后一个/ nameOfMyAssembly。 DLL。我可以成功地保存在此位置第三方.DLL(这最终被(C:\ Documents和Settings \ MyUserName输入\本地设置\应用数据\装配\ d13的\ KXPPAX6Y.ZCY \ A1MZ1499.1TR \ e0115d44 \ 91bb86eb_fe18c901)但是当我到达我的code,要求该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?

推荐答案

一旦你嵌入的第三方组件作为资源,增加code订阅AppDomain.AssemblyResolve活动期间,应用程序启动时的电流域。这每当CLR的融合子系统无法根据探测(政策)的影响,以找到一个组件事件触发。在事件处理程序 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.