.NET在运行时加载程序集

时间:2009-01-22 06:48:13

标签: c# .net reflection assemblies

我前一段时间发过一个类似的问题。我需要在运行时加载程序集。

如果我在运行时知道dll的绝对路径,这很容易。

但我没有:(如果文件不在应用程序根目录中,assembly.Load()或LoadFromFile()将失败。

我唯一拥有的是dll名称。 dll可以位于root,system32或甚至GAC中。

.net是否可以自动确定dll所在的位置,例如: 它应该首先查看根。如果不在那里移动到系统文件夹,则尝试GAC。

EDITED

我正在使用插件架构。我不需要注册dll。我有一个多用户应用程序。我有一个包含应用程序信息的应用程序表。每个应用程序都有一个与之关联的dll路径,包含与该应用程序关联的某些算法。希望这会有所帮助。

9 个答案:

答案 0 :(得分:2)

您可以连接到AppDomain.CurrentDomain.AssemblyResolve事件并根据需要手动加载应用程序的程序集。

答案 1 :(得分:2)

当前应用程序查找程序集时,它会查找多个位置(bin文件夹,gac等等),如果找不到,那么开发人员需要手动告诉应用程序在哪里查找。您可以通过拦截AssemblyResolve事件并使用事件参数告诉CLR汇编所在的位置来完成此操作。

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
....................
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
   var strTempAssmbPath=
          Path.GetFullPath("C:\\Windows\\System32\\" + args.Name.Substring(0,  args.Name.IndexOf(",")) + ".dll");

   var strTempAssmbPath2=
          Path.GetFullPath("C:\\Windows\\" + args.Name.Substring(0,  args.Name.IndexOf(",")) + ".dll");


    if (File.Exists(strTempAssmbPath))
            return Assembly.LoadFrom(strTempAssmbPath);

    if (File.Exists(strTempAssmbPath2))
            return Assembly.LoadFrom(strTempAssmbPath2);
}

答案 2 :(得分:1)

如果在PATH系统变量(即system32)中引用的某个位置或者如果注册了dll,则会自动找到该DLL。如果它可以在磁盘上任何地方找不到它,但无论如何都没有人需要这个功能。

编辑:dll可以注册吗?如果你不提前知道装配,你如何获得装配名称?您是否正在创建某种类型的插件架构?我认为如果你更多地解释一下你的情况会有所帮助。

EDIT2:如果是这种情况,为什么不为用户提供注册他或她的插件的方法?您可以从打开的文件对话框中获取所需的所有信息。那或者只是让它们将它转储到你指定的文件夹中。

答案 3 :(得分:1)

是的,有一种方法,这取决于你的dll是弱(没有公钥令牌)还是强(用公钥令牌)命名。如果它的名称很弱并且您在VS中添加了对带有dll的程序集的引用,那么VS将首先查看应用程序文件夹根目录,如果找不到它,它将查找您指定为值的子目录您的XML配置文件中的privatePath属性。

如果它是一个强名称的dll,那么CLR将在GAC中搜索,因此您需要在GAC中安装dll。如果您安装的XML配置文件的codeBase元素指向dll的路径,CLR也可以查看应用程序目录。

要在GAC中指定程序集,可以在编译程序集时使用/ reference:[DLL name]开关。

答案 4 :(得分:1)

我希望您已阅读以下内容。我的建议......

  • How the runtime locates assemblies
  • 你可以给Assembly。 LoadWithPartialName 一个旋转......可能有效.. it says it will search the application folder and the GAC与Assembly.Load不同。 (但它的安全性较低..因为你没有指定程序集名称的所有4个部分,你最终可能会得到错误版本的DLL)
  • 同时尝试AppDomainSetup.PrivateBinPath(已弃用AppDomain.AppendPrivatePath以支持此操作),将应用程序根目录的子文件夹添加到要探测程序集的文件夹列表中。您还可以尝试将来自其他地方的文件复制到[AppFolder] \ MySandboxForDLLsToLoad中,该文件已添加到PrivateBinPath中。

答案 5 :(得分:1)

你有三个选择

  1. 在全局程序集缓存(GAC)中安装程序集
  2. 使用带有标记的应用程序配置(.config)文件
  3. 使用AssemblyResolve事件
  4. 您可以找到详细信息here

答案 6 :(得分:1)

.NET用于查找程序集及其依赖项的解析算法很简单。

  1. .NET标识所需的版本。通常,有关依赖程序集的信息存在于应用程序的程序集清单中。
  2. .NET仅在程序集强名称时搜索GAC(全局程序集缓存)。
  3. 如果在GAC中找不到,并且.config文件存在,则.NET搜索cofiguration文件中指定的位置,否则.NET搜索包含可执行文件的目录(.EXE)
  4. 此后,如果仍未找到程序集,则应用程序将终止并显示错误。
  5. Click here用于解释.net解析算法的视频,click here用于关于后期绑定程序集的视频

答案 7 :(得分:0)

将此程序集注册到GAC中。 How to do that

答案 8 :(得分:0)

使用它 Assembly.LoadWithPartialName(的AssemblyName);