从另一个文件夹中parsing程序集引用

我正在开发一个应用程序,引用和使用某个Vendor的一些第三方程序集; 在开发框中我有这3个程序集在我的源代码树中的参考文件夹中,我可以引用它们并构build应用程序,应用程序构build,但不会运行,因为整个服务器应用程序未安装,但这是好的。

在我想要复制这个自定义应用程序的服务器上,运行我所引用的所有程序集都在文件夹中,如:

D:\ProgramFiles\VendorName\ProductName\Support\API\Bin64 

如果我复制我的小可执行文件在该文件夹中运行它,它完美的作品,但如果我把我的.exe在一个更合适的文件夹就像我想要的:

 D:\ProgramFiles\MyCompanyName\MyProduct\bin\... 

它不起作用,因为它不能解决这些程序集。

我知道我可以在app.config中使用探测来指定我的EXE必须在哪个文件夹中查找引用,但是,如果程序集不在子文件夹中,更多的位于完全不同的位置。

我不想复制在我的应用程序文件夹中的所有供应商程序集,我不能只有那3个我引用,因为他们也加载其他程序集,除非我拥有所有这些(很多…),它不工作。

我没有做任何特别的事情,没有创build应用程序域,也没有通过reflection来加载程序集,只是希望CLR在应用程序启动或执行时parsing引用。

谢谢。

编辑:这里是最后的工作代码

 static System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { Logger logger = new Logger(); try { string RMSAssemblyFolder = ConfigurationManager.AppSettings["RMSAssemblyFolder"]; Assembly MyAssembly = null; string strTempAssmbPath = string.Empty; Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly(); AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies(); AssemblyName myAssemblyName = Array.Find<AssemblyName>(arrReferencedAssmbNames, a => a.Name == args.Name); if (myAssemblyName != null) { MyAssembly = Assembly.LoadFrom(myAssemblyName.CodeBase); } else { strTempAssmbPath = Path.Combine(RMSAssemblyFolder, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"); if (!string.IsNullOrEmpty(strTempAssmbPath)) { if (File.Exists(strTempAssmbPath)) { logger.Information("Assembly to load: {0} - File was found in: {1}", args.Name, strTempAssmbPath); // Loads the assembly from the specified path. MyAssembly = Assembly.LoadFrom(strTempAssmbPath); } } } // Returns the loaded assembly. return MyAssembly; } catch (Exception exc) { logger.Error(exc); return null; } } 

您应该首先find安装这些dll的文件夹,然后使用AppDomain.AssemblyResolve钩住程序集parsing并尝试从该文件夹中加载所请求的程序集。

它看起来像这样(没有testing,你需要检查args.Name包含的是什么,可以包含版本和强名称以及types名称):

 var otherCompanyDlls = new DirectoryInfo(companyFolder).GetFiles("*.dll"); AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var dll = otherCompanyDlls.FirstOrDefault(fi => fi.Name == args.Name); if (dll == null) { return null; } return Assembly.Load(dll.FullName); }; 

使用SN.exe :SN -T VendorAssembly.dll,这将返回一个hex数字,这是公钥标记,然后,从app.config引用程序集。 要获取版本,请右键单击您的供应商程序集,并将其用于codeBase版本值,即您提到的href =path。

  <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="VendorAssembly" culture="neutral" publicKeyToken="307041694a995978"/> <codeBase version="1.1.1.1" href="FILE://D:/ProgramFiles/VendorName/ProductName/Support/API/Bin64/VendorAssembly.dll"/> </dependentAssembly> </assemblyBinding> </runtime> </configuration>