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);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM