C#: Could not load file or assembly

Exception:

Could not load file or assembly 'DllFileName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cadd04e079758c3' or one of its dependencies. The system cannot find the file specified.

最近在研究动态读取非当前EXE目录的DLL文件的方法。

Reflection, Activator.CreateInstance,或者AppDomain啥的。

当只读取单个Dll的时候没啥问题,但是当这个Dll以来和它同一个文件夹的dll时,就会报错。

搜了很久,终于搜到篇靠谱的文章。

http://theraneman.blogspot.com/2010/04/creating-instance-of-type-outside.html

文章是2010年的,10年过去了,呵呵。。。

大致解决方法代码如下,直接COPY过来留个念,慢慢啃。


 

1. 一般操作,会导致报错

Assembly assembly = Assembly.LoadFrom(C:\Sample\Sample.dll);
Type appType = assembly.GetType(MyType);
object objClassInstance = Activator.CreateInstance(appType);

2. 解决方案一

有点过的方案,哈哈,

使用这个方法,不能直接实例化你需要的函数,而必须实例化一个继承了MarshalByRefObject的函数,

入下面代码中的SampleProxy

Assembly assembly = Assembly.LoadFrom(@"C:\Sample\Sample.dll");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = @"C:\Sample\";
AppDomain appDomain = AppDomain.CreateDomain("AppHostDomain", null, setup);
object obj = appDomain.CreateInstanceFromAndUnwrap(@"C:\Sample\Sample.dll", "SampleProxy");

3.解决方案二

被原作者成为冗余啰嗦的方案,不过在我看来挺好的。

该方案将循环递归加载所依赖的DLL

Assembly assembly = Assembly.LoadFrom(@"C:\Sample\Sample.dll"); 
AssemblyName[] arr
= assembly.GetReferencedAssemblies(); LoadAssembly(arr); private void LoadAssembly(AssemblyName[] arr) { Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); List<string> names = new List<string>(); foreach (Assembly assem in loadedAssemblies) { names.Add(assem.FullName); } foreach (AssemblyName aname in arr) { if (!names.Contains(aname.FullName)) { try { Assembly loadedAssembly = Assembly.LoadFrom(@"C:\Sample\" + aname.Name + ".dll"); AssemblyName[] referencedAssemblies = loadedAssembly.GetReferencedAssemblies(); LoadAssembly(referencedAssemblies); } catch (Exception ex) { continue; } } } }

3. 解决方案三

定于当前AppDomain的一个事件,就是当需要哪个Assembly而又找不到时,就会触发。

Assembly assembly = Assembly.LoadFrom(@"C:\Sample\Sample.dll");
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
object obj = Activator.CreateInstanceFrom(@"C:\Sample\Sample.dll", "MyType");

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string path = @"C:\Sample\Sample.dll";
    string test = path.Substring(0,path.LastIndexOf(@"\"));
    string[] arr = args.Name.Split(',');
    string assemblyName = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
    string newPath = System.IO.Path.Combine(test, assemblyName);
    return Assembly.LoadFrom(newPath);
}

 

posted @ 2020-04-06 21:11  No5Meters  阅读(8732)  评论(0编辑  收藏  举报