2009-01-22 93 views
4

我前一段时间发布了类似的问题。我需要在运行时加载程序集。.NET在运行时加载程序集再次

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

但我不:(在assembly.Load()或LoadFromFile()如果文件不是在应用程序根失败。

我的唯一的事情是DLL的名称。该DLL可以设在系统32或甚至在GAC中。

是否有可能让.net自动确定dll所在的位置,例如: 它应该首先查看根。如果它不存在系统文件夹,否则试试GAC。

EDITED

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

回答

1

该DLL将被自动找到它是在PATH系统变量(即system32)中引用的某个位置,或者如果该DLL已注册。如果磁盘上的任何地方都可以使用,但无法找到该功能,但无法找到该功能。

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

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

+0

当我打电话的assembly.Load(“MyAssembly.dll程序”),我把该dll我system32,它不起作用。 – MegaByte 2009-01-22 06:53:55

+0

我认为这适用于非托管DLL而非托管DLL。看到Lonzo的帖子,我认为什么是更好的回应。 – Gishu 2009-01-22 07:20:32

2

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

+0

好吧,所以一旦我设置了所有其他路径 - 我如何告诉CLR加载程序集?我仍然使用Load()方法吗? – MegaByte 2009-01-22 08:10:52

1

是的有一种方法,它取决于你的DLL是弱(没有公钥标记)或强烈(与公钥标记)命名。如果它的名字很弱,并且你在VS中添加了一个dll的程序集引用,那么VS将首先查找应用程序的文件夹根目录,如果它没有找到它,它会查找你指定的子目录中的值您的XML配置文件中的privatePath属性。

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

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

1

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

  • How the runtime locates assemblies
  • 你可以给大会。 LoadWithPartialName旋转..可能工作.. it says it will search the application folder and the GAC不像Assembly.Load。 (然而,它不太安全..因为你可能以错误版本的DLL结束,因为你没有指定程序集名称的全部4部分)
  • 另请尝试AppDomainSetup.PrivateBinPath(AppDomain.AppendPrivatePath已被弃用, )将应用程序根目录的子文件夹添加到要探测程序集的文件夹列表中。您也可以尝试将其他位置的文件复制到添加到PrivateBinPath的[AppFolder] \ MySandboxForDLLsToLoad中。
0

使用此 Assembly.LoadWithPartialName(assemblyName);

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); 
} 
1

你有三个选择

  1. 在全局程序集缓存中安装的组件(GAC)
  2. 使用应用程序配置(的.config)与标签
  3. 使用AssemblyResolve事件文件

你可以找到详细信息here

1

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

  1. .NET标识所需的版本。通常,关于相关程序集的信息出现在应用程序的程序集清单中。
  2. .NET仅搜索GAC(全局程序集缓存),只有在程序集名为strong的情况下。
  3. 如果在GAC中找不到,并且如果.config文件存在,那么.NET会搜索配置文件中指定的位置,否则.NET搜索包含可执行文件(.EXE)的目录。
  4. 之后,如果程序集仍然没有找到,应用程序因错误而终止。

Click here的视频解释.NET解析算法,并click here对后期绑定组件的视频