特投网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

(站外) 特投工作室

查看: 3367|回复: 0

C#中集成dll到exe中的方法

[复制链接]

2569

主题

1018

回帖

6万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
69667
QQ
发表于 2016-5-27 15:00:54 | 显示全部楼层 |阅读模式
【最新整理: 2013-04-11】
把dll文件添加为资源文件
项目属性->Resources->Add Resource->Add Existing File:
然后注意设置过滤规则为 *.*,才能显示出来dll文件,然后把dll添加进来:
把dll文件添加到项目中
【此步骤可选】右击项目->添加->新建文件夹:
再导入对应的dll文件:
然后选择对应dll,导入即可。
设置项目中的DLL文件为“嵌入的资源”
然后,在左边的项目列表中,点击对应的dll文件,右键选择属性,设置“生成操作”为“嵌入的资源”:
其中,如果是英文环境,对应的是把"Build Action"设置为"Embedded Resource"
表示,此项目会把此dll集成到生成的(exe)文件中,以此实现dll先集成到生成的exe文件本身中。
通过Reflection代码实现载入内置的(dll)资源文件
把下面代码,添加到你的项目的主类中:
...
  
namespace downloadSongtasteMusic
{
    class songtaste
    {
...
        public songtaste()
        {
            ...
  
            AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }
  
        System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
  
            dllName = dllName.Replace(".", "_");
  
            if (dllName.EndsWith("_resources")) return null;
  
            System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
  
            byte[] bytes = (byte[])rm.GetObject(dllName);
  
            return System.Reflection.Assembly.Load(bytes);
        }
         
        ...
    }
}
如此,其会在主程序初始化的时候,就去把内在的那些资源文件,此处包括你所添加的dll文件,载入尽量,实现了载入dll库文件(相关的函数)的目的。
因此,你的程序调用dll中的函数,也才能找到合适的函数,而不会出现找不到函数,找不到dll库的问题。

至此,就实现了,C#中将dll集成到exe中的目的了。
注意事项:
1.把dll添加作为资源文件,之前以为是可以省略的呢,后来证实,这一步是必不可少的。否则,也是无法把dll集成进来的。
2. 对于上述,在类初始化函数中的,要添加的那句:
AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
千万不能忘了!!!
否则就像我此处,调试了半天,最终也没有实现对应的集成dll到exe的效果。
最后是找到此处忘了添加这句,导致没有集成dll成功。
所以,千万不要犯和我此处同样的错误。
3.只是把dll导入为资源(res)文件后,在项目文件列表中,是看不到对应的文件的;
只能是,另外再导入现存的dll文件,才能在项目文件列表中,看到对应的dll,才能选择该dll,设置为嵌入的资源;
4.不同的类,比如一个winForm类frmFiverrComScraper.cs,另外一个我自己的库crifanLib.cs,
如果使用到了对应的dll(中的类),那么,分别都要在自己的类的构造函数中,加入对应的
AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {…..}
部分的代码的。
当然,多个类,可以通用一份CurrentDomain_AssemblyResolve的代码实现。
5.如果exe是在网上邻居/网络共享中运行的话,可能会出现问题,详情参考:
但是如果是本地,即当前电脑的硬盘上运行,则不会出现这类问题的。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

您尚未登录,请登录后浏览更多精彩内容!
 立即注册
找回密码

QQ|Archiver|手机版|小黑屋|特投网 ( 皖ICP备13010674号-1 

GMT+8, 2024-3-29 01:26 , Processed in 0.028508 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表