. net参考dll从其他位置

本文关键字:其他 位置 dll 参考 net | 更新日期: 2023-09-27 18:04:48

我正在制作一个依赖第三方程序中包含的一些dll的程序。我不允许自己分发这些dll。必须安装第三方程序才能使我的程序工作。

如何引用这些dll ?我通过程序设置的注册表项知道它们的确切位置。

我试图在项目中添加文件->引用并将CopyLocal设置为false,但当我开始时,我会得到一个FileNotFoundException "无法加载文件或程序集"。

我试图添加一个事件到AppDomain.CurrentDomain.AssemblyResolve并加载那里的文件,但问题是,我得到异常之前,我的程序甚至开始。即使我把断点放在第一行,异常也会在断点被击中之前被抛出。

. net参考dll从其他位置

选自 c# 3.0 in a Nutshell,第3版,by Joseph and Ben Albahari, p. 557-558:

在基本文件夹外部署程序集

有时您可能会选择将程序集部署到应用程序基目录以外的位置[…]要使此工作,您必须协助CLR在基本文件夹外查找程序集。最简单的解决方案是处理AssemblyResolve事件。

(我们可以忽略这样一个事实,即在您的情况下,其他人正在部署程序集。)

你试过了。但一个非常重要的线索随后出现。阅读这两个代码注释:

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
    }
}
如您所见,解析外部程序集的类不能引用任何外部dll 中的任何类型如果是这样,代码执行将在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。