从另一个文件夹中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>
- 文件写入权限问题“Program Files”文件夹下
- 如何在C#/ .NET中将file upload到SFTP服务器?
- string.ToLower()和string.ToLowerInvariant()
- 我如何获得System.Web.Http.Owin?
- parsingdate时间与PST / CEST / UTC /等forms的时区
- 在C#控制台应用程序中隐藏控制台窗口
- WCF服务客户端:内容typestext / html; 响应消息的charset = utf-8与绑定的内容types不匹配
- 安全处理exception时避免第一次机会exception消息
- C#XmlSerializer BindingFailure