. net参考dll从其他位置
本文关键字:其他 位置 dll 参考 net | 更新日期: 2023-09-27 18:04:48
我正在制作一个依赖第三方程序中包含的一些dll的程序。我不允许自己分发这些dll。必须安装第三方程序才能使我的程序工作。
如何引用这些dll ?我通过程序设置的注册表项知道它们的确切位置。
我试图在项目中添加文件->引用并将CopyLocal设置为false,但当我开始时,我会得到一个FileNotFoundException "无法加载文件或程序集"。
我试图添加一个事件到AppDomain.CurrentDomain.AssemblyResolve并加载那里的文件,但问题是,我得到异常之前,我的程序甚至开始。即使我把断点放在第一行,异常也会在断点被击中之前被抛出。
选自 c# 3.0 in a Nutshell,第3版,by Joseph and Ben Albahari, p. 557-558:
在基本文件夹外部署程序集
有时您可能会选择将程序集部署到应用程序基目录以外的位置[…]要使此工作,您必须协助CLR在基本文件夹外查找程序集。最简单的解决方案是处理
AssemblyResolve
事件。
(我们可以忽略这样一个事实,即在您的情况下,其他人正在部署程序集。)
你试过了。但一个非常重要的线索随后出现。阅读这两个代码注释:
如您所见,解析外部程序集的类不能引用任何外部dll 中的任何类型。如果是这样,代码执行将在public static void Loader { static void Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += FindAssem; // We must switch to another class before attempting to use // any of the types in C:'ExtraAssemblies: Program.Go(); } static Assembly FindAssem(object sender, ResolveEventArgs args) { string simpleName = new AssemblyName(args.Name).Name; string path = @"C:'ExtraAssemblies'" + simpleName + ".dll"; if (!File.Exists(path)) return null; return Assembly.LoadFrom(path); } } public class Program { public static void Go() { // Now we can reference types defined in C:'ExtraAssemblies } }
AssemblyResolve
有机会运行之前停止。
你的应用会爆炸,因为JIT编译器是第一个需要加载程序集的编译器。您需要小心避免在Main()方法中使用程序集中的类型。这不难做到,只需要再写一个Main方法并给它一个属性告诉jitter永远不要内联那个方法。如果没有这个属性,当优化器内联该方法时,它仍然可能在发布版本中爆炸。这样的:
using System;
using System.Runtime.CompilerServices;
class Program {
static void Main(string[] args) {
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
DelayedMain(args);
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void DelayedMain(string[] args) {
// etc..
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
// etc...
}
}
在你这样做之前,一定要联系供应商并征求他们的建议。必须有一种更简单的方法来行使您的许可权利。GAC将是一个常见的选择,也许您只需要在您的开发机器上运行gautil。