.net 使用Assembly.LoadFrom和Assembly.Load混合加载程序集时的奇怪行为

.net 使用Assembly.LoadFrom和Assembly.Load混合加载程序集时的奇怪行为,.net,assemblies,assembly.load,.net,Assemblies,Assembly.load,使用Assembly.LoadFrom和Assembly.Load混合加载程序集时的奇怪行为 使用Assembly.LoadFrom加载程序集时,以及以后使用Assembly.Load加载程序集时,我遇到了一个奇怪的行为。 我正在使用assembly.LoadFrom加载程序集,其中程序集位于非执行文件夹的文件夹中 稍后在我的测试代码中,当我尝试使用assembly.load再次加载此程序集时,加载失败,出现System.IO.FileNotFoundException(“无法加载文件或程序集…

使用Assembly.LoadFrom和Assembly.Load混合加载程序集时的奇怪行为

使用Assembly.LoadFrom加载程序集时,以及以后使用Assembly.Load加载程序集时,我遇到了一个奇怪的行为。
我正在使用assembly.LoadFrom加载程序集,其中程序集位于非执行文件夹的文件夹中

稍后在我的测试代码中,当我尝试使用assembly.load再次加载此程序集时,加载失败,出现System.IO.FileNotFoundException(“无法加载文件或程序集…”),尽管该程序集已加载。强名称和非强名称的加载都失败(再次加载此程序集的最初原因是使用了BinaryFormatter)

但是,如果程序集位于execution文件夹中,则后面的加载在这两种情况下都会成功,包括强名称和非强名称。在这种情况下,您可以看到从两个不同的位置加载了两个相同的程序集

重现此问题的简单代码示例——

Assembly Assembly 1=Assembly.LoadFrom(@“C:\a.dll”)

//使用强名称加载失败 组件2=组件加载(@“a,版本=1.0.0.0, 文化=中性,PublicKeyToken=14986c3f172d1c2c”)

//使用非强加载也会失败 组件3=组件负载(@“a”)

  • 有没有解释为什么CLR忽略已加载的程序集
  • 你知道我该如何缓解这个问题吗

  • 谢谢。

    这并不奇怪。根据文档,使用Load和LoadFrom加载将在不同的上下文中放置程序集。也许会有帮助

  • 有没有解释为什么CLR忽略已加载的程序集
  • 因为他们处于不同的环境中

  • 你知道我该如何缓解这个问题吗
  • 从同一上下文加载,或帮助CLR查找程序集,方法可能是将处理程序附加到
    AppDomain.AssemblyResolve

    备选方案

    如果加载程序集的位置是AppDomain.BaseDirectory下的子文件夹,则只需在App.config中添加一个条目:

    <configuration>
       <runtime>
          <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
             <probing privatePath="bin;bin2\subbin;bin3"/>
          </assemblyBinding>
       </runtime>
    </configuration>
    
    
    @Kent Boogart:
    这似乎是正确的解释。苏珊娜·库克(Suzanne Cook)的这篇博文比你最初发表的博文要详细一些,以作全面解释:
    

    下面是利用AppDomain.AssemblyResolve的代码-

     // register to listen to all assembly resolving attempts:
     AppDomain currentDomain = AppDomain.CurrentDomain;
     currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
    
    
     // Check whether the desired assembly is already loaded
     private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
        Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
        foreach (Assembly assembly in assemblies) {
           AssemblyName assemblyName = assembly.GetName();
           string desiredAssmebly = args.Name;
           if (assemblyName.FullName == desiredAssmebly) {
               return assembly;
           }
        }
    
        // Failed to find the desired assembly
        return null;
     }