C#下反射动态加载dll后如何卸载?

最近在做项目的时候,遇到一个需求,需要通过选择的文件,先判断是C#dll还是C++dll,再判断dll是否是我们需要的特定dll,还是别的随便一个dll。

经过研究发现,我们可以通过反射来加载dll,如果用C#的反射机制可以正确加载dll,那么就可以认为该dll是C#类型的,如果不能正确加载,我们再通过C++的方法来加载进行判断。

判断是否特定dll的话,只需在判断完dll类型后,对dll中的特定类进行判断即可。

但是这里,存在一个问题,通过反射加载完C#dll后,该dll即被占用,无法进行修改(比如,我判断完该dll后,发现该dll版本选错了,那么此时,是没办法进行替换的,因为已经被程序加载了),此时,我们即需要对反射加载的该类进行卸载。

尴尬的是,C#并没有对Assembly定义释放方法,这是因为,反射加载完的对象是通过CLR进行托管的,只有等到对象无用时,才会通过GC进行回收。但这明显不能满足我们的需求。

其实,这个问题是可以通过应用程序域来解决的。

要对dll进行判断时,我们可以创建一个应用程序域,通过应用程序域的方法来动态加载反射,并且,其提供的UnLoad方法,可以将加载的dll给动态的卸载掉。

如,我这里是这么处理的。

            AppDomain appDomain = AppDomain.CreateDomain("CheckDllType");

            try
            {
                //判断文件存在不存在
                if (!File.Exists(dllPath))
                    return res;

                //用C#加载DLL的方法进行加载dll尝试
                object ob_CAN = appDomain.CreateComInstanceFrom(dllPath, "Unify.Bootloader");
                if (ob_CAN!=null)
                {
                    res = 1;
                    //释放对象
                    AppDomain.Unload(appDomain);
                    appDomain = null;
                    ob_CAN = null;
                }
            }
            catch (Exception ex)//若异常,则判断其他类型
            {
                //....
            }

注意,这里会把新创建域中的所有对象都给回收。

另外一个应用场景就是,当我们需要做一个反编译工具时,也需要用到这样的处理,因为不能每次dll更新后都重启反编译软件。

同时,这里创建域是有一组不同的方法的,并且每个方法都有多个重载,包括

CreateComInstanceFrom
CreateInstance
CreateInstanceAndUnwrap
CreateInstanceFrom
CreateInstanceFromAndUnwrap

有需要的大家可以自行学习,注意其间的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值