首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将一个dll作为嵌入式资源嵌入到另一个dll中,然后从我的代码中调用它

将一个dll作为嵌入式资源嵌入到另一个dll中,然后从我的代码中调用它
EN

Stack Overflow用户
提问于 2008-09-18 20:43:00
回答 6查看 49.6K关注 0票数 57

在这种情况下,我有一个正在创建的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\

Data\assembly\dl3\KXPPAX6Y.ZCY\A1MZ1499.1TR\e0115d44\91bb86eb_fe18c901

),但是当我读到需要这个DLL的代码部分时,它找不到它。

有没有人知道我需要做些什么改变?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2008-09-18 21:40:49

将第三方程序集作为资源嵌入后,添加代码以在应用程序启动期间订阅当前域的AppDomain.AssemblyResolve事件。只要CLR的Fusion子系统无法根据生效的探测(策略)找到程序集,就会触发此事件。在AppDomain.AssemblyResolve的事件处理程序中,使用Assembly.GetManifestResourceStream加载资源,并将其内容作为字节数组提供给相应的Assembly.Load重载。下面是一个这样的实现在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可能是另一个要考虑的选择,尽管涉及的内容更多一些。

票数 44
EN

Stack Overflow用户

发布于 2008-09-19 17:11:38

最后,我几乎完全按照raboof建议的方式做了(和dgvid建议的类似),只是做了一些小改动和一些遗漏。我之所以选择这种方法,是因为它最接近我最初寻找的东西,而且不需要使用任何第三方可执行文件等。它工作得很好!

这就是我的代码最终的样子:

编辑:我决定将这个函数移到另一个程序集中,这样我就可以在多个文件中重用它(我只是传入了Assembly.GetExecutingAssembly())。

这是更新后的版本,它允许您传入带有嵌入的dll的程序集。

embeddedResourcePrefix是嵌入资源的字符串路径,它通常是程序集的名称,后跟包含资源的任何文件夹结构(例如"MyComapny.MyProduct.MyAssembly.Resources“,如果dll位于项目中一个名为Resources的文件夹中)。它还假设dll具有.dll.resource扩展名。

   public static void EnableDynamicLoadingForDlls(Assembly assemblyToLoadFrom, string embeddedResourcePrefix) {
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { // had to add =>
            try {
                string resName = embeddedResourcePrefix + "." + args.Name.Split(',')[0] + ".dll.resource";
                using (Stream input = assemblyToLoadFrom.GetManifestResourceStream(resName)) {
                    return input != null
                         ? Assembly.Load(StreamToBytes(input))
                         : null;
                }
            } catch (Exception ex) {
                _log.Error("Error dynamically loading dll: " + args.Name, ex);
                return null;
            }
        }; // Had to add colon
    }

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

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

            return output.ToArray();
        }
    }
票数 21
EN

Stack Overflow用户

发布于 2008-09-18 20:48:44

有一个叫做IlMerge的工具可以做到这一点:http://research.microsoft.com/~mbarnett/ILMerge.aspx

然后,您可以创建一个类似于以下内容的build事件。

设置Path="C:\Program Files\Microsoft\ILMerge“

取消合并/out:$(ProjectDir)\Deploy\LevelEditor.exe $(ProjectDir)\bin\Release\release.exe $(ProjectDir)\bin\Release\InteractLib.dll $(ProjectDir)\bin\Release\SpriteLib.dll $(ProjectDir)\bin\Release\LevelLibrary.dll

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/96732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档