none
c#程序dll动态加载问题? RRS feed

  • 问题

  • 我有一个c#程序,用了devexpress的窗体,我把所需的dll添加到资源文件,然后把exe拷贝到一个没有dev环境的电脑上运行,如何释放我资源文件里面的dll,并动态加载,然后正常运行程序?

    我写过几个例子,好像还没进入main函数就报错了。
    2017年11月1日 9:16

答案

  • 1  从资源文件中读取dll ,释放到硬盘中,通用的写法

    private static void ExtractEmbeddedResource(string outputDir, string resourceLocation, List<string> files) { foreach (string file in files) { using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceLocation + @"." + file)) { using (System.IO.FileStream fileStream = new System.IO.FileStream(System.IO.Path.Combine(outputDir, file), System.IO.FileMode.Create)) { for (int i = 0; i < stream.Length; i++) { fileStream.WriteByte((byte)stream.ReadByte()); } fileStream.Close(); } } } }

    动态加载就复杂一些了,要考虑反射,编译时还不能直接引用,不推荐。

    我列一个变通的方法,本机开发时,项目添加引用需要的dll, 同时将这些dll 嵌入到资源文件中,

    部署到客户电脑中时,添加如下方法,直接从dll中加载程序集(可以忽略第一步)

    Assembly.GetExecutingAssembly().GetManifestResourceStream()

    Assembly.Load 这一个方法可以直接传入一个字节流,也就是从资源文件中获取的DLL的字节流

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(    
    (s, a) =>
    {
        if (a.Name.Substring(0, a.Name.IndexOf(",")) == "AxInterop.WMPLib")
        {
            return Assembly.Load(res.AxInterop_WMPLib);
        }
    
        if (a.Name.Substring(0, a.Name.IndexOf(",")) == "Interop.WMPLib")
        {
            return Assembly.Load(res.Interop_WMPLib);
        }
    
        return null;
    }

    查看具体例子

    https://www.codeproject.com/articles/528178/load-dll-from-embedded-resource

    Load DLL From Embedded Resource - CodeProject

    Load DLL From Embedded Resource


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    • 已标记为答案 小污云 2017年11月2日 1:25
    2017年11月2日 0:53

全部回复

  • 1  从资源文件中读取dll ,释放到硬盘中,通用的写法

    private static void ExtractEmbeddedResource(string outputDir, string resourceLocation, List<string> files) { foreach (string file in files) { using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceLocation + @"." + file)) { using (System.IO.FileStream fileStream = new System.IO.FileStream(System.IO.Path.Combine(outputDir, file), System.IO.FileMode.Create)) { for (int i = 0; i < stream.Length; i++) { fileStream.WriteByte((byte)stream.ReadByte()); } fileStream.Close(); } } } }

    动态加载就复杂一些了,要考虑反射,编译时还不能直接引用,不推荐。

    我列一个变通的方法,本机开发时,项目添加引用需要的dll, 同时将这些dll 嵌入到资源文件中,

    部署到客户电脑中时,添加如下方法,直接从dll中加载程序集(可以忽略第一步)

    Assembly.GetExecutingAssembly().GetManifestResourceStream()

    Assembly.Load 这一个方法可以直接传入一个字节流,也就是从资源文件中获取的DLL的字节流

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(    
    (s, a) =>
    {
        if (a.Name.Substring(0, a.Name.IndexOf(",")) == "AxInterop.WMPLib")
        {
            return Assembly.Load(res.AxInterop_WMPLib);
        }
    
        if (a.Name.Substring(0, a.Name.IndexOf(",")) == "Interop.WMPLib")
        {
            return Assembly.Load(res.Interop_WMPLib);
        }
    
        return null;
    }

    查看具体例子

    https://www.codeproject.com/articles/528178/load-dll-from-embedded-resource

    Load DLL From Embedded Resource - CodeProject

    Load DLL From Embedded Resource


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    • 已标记为答案 小污云 2017年11月2日 1:25
    2017年11月2日 0:53
  • 谢谢,我昨天晚上已经搞定了。
    2017年11月2日 1:25