最近做一个项目需要程序动态的加载执行dll,这个dll需要从远程服务器上下载最新版本,当本地版本低于远程服务器上的版本就下载dll,然后程序加载最新的dll。在写代码过程中遇到了一个问题,当程序执行了一遍dll后,再次执行的时候,发现服务器上有新版本,那么就删除本地的dll,这个时候就报错写保持,原因是执行第一遍的时候已经将dll加载到项目中,这个时候这个文件就被写保护了,所以删除的时候就会报错。查询网上有的用appDomain,但本人内功不深厚没有试验成功,总是提示有依赖没有加载上,还好条条大路通罗马,最终在使用反射加载dll的时候不使用LoadFile(FilePath),该成使用LoadFile(File.ReadAllBytes(FilePath))的方式反射就可以了,原因应该文件以二进制读取后读到了内存在,在内存中执行dll方法与文件无关了,所以再次下载删除dll时就不会有写保护了。代码如下:
// 动态加载刚下载的dll
string assemblyPath = Directory.GetCurrentDirectory();
if(File.Exists(assemblyPath + @"\Math.dll"))
{
File.Delete(assemblyPath + @"\Math.dll");
}
File.Copy(@"F:\book\practiceG\CheckXml\Math\bin\Debug\netstandard1.4\Math.dll", assemblyPath + @"\Math.dll");
Assembly assem = Assembly.Load(System.IO.File.ReadAllBytes(assemblyPath + @"\Math.dll"))
Type ty = assem.GetType("Math");
// 获取不带参数的构造函数
ConstructorInfo magicConstructor = ty.GetConstructor(Type.EmptyTypes);
// 这里是获取一个类似于类的实例的东东
object magicClassObject = magicConstructor.Invoke(new object[] { });
MethodInfo mi = ty.GetMethod("Add");
object result = mi.Invoke(magicClassObject, new object[] { 1,2 });
MessageBox.Show(Convert.ToInt32(result).ToString());
希望给遇到同样问题的同仁有参考意义,同时appDomain还需要继续研究一下。