【问题标题】:Why FileNotFoundException when I Assembly.Load an assembly that is surely present?为什么在我 Assembly.Load 肯定存在的程序集时出现 FileNotFoundException?
【发布时间】:2011-06-22 12:51:31
【问题描述】:

在我的 Windows Azure 角色 C# 代码中,我执行以下操作:

Assembly.Load( "Microsoft.WindowsAzure.ServiceRuntime" );

FileNotFoundException 被抛出。问题是存在具有此类名称的程序集,甚至在运行上述代码之前就已加载 - 我在调试器“输出”窗口中看到相应的行,当我这样做时:

AppDomain.CurrentDomain.GetAssemblies().Any(
    assembly => assembly.FullName.StartsWith("Microsoft.WindowsAzure.ServiceRuntime"));

结果是true,如果我使用Where(),那么SingleOrDefault() 我会得到一个对相应Assembly 对象的引用。

为什么我不能用Assembly.Load() 加载程序集?

【问题讨论】:

  • 也许不是这个程序集,而是它的依赖项之一,例如本机 dll 丢失了?
  • @Armen Tsirunyan:也许吧,但是已经加载了相同的程序集——我在调试器输出中看到了。
  • 我转向使用绝对路径:Assembly.LoadFrom(path),我在网络服务器上,我使用路径为string path = HttpRuntime.AppDomainAppPath + "bin\\XXXX.dll"

标签: c# .net reflection azure


【解决方案1】:

只有在 Microsoft.WindowsAzure.ServiceRuntime.dll 存储在应用程序的探测路径中时,该 Load() 调用才能成功。默认情况下,与您的 EXE 相同的目录。问题是,它没有存储在那里,而是存储在 GAC 中。

GAC 的目的是充当具有相同名称但不同 [AssemblyVersion]、文化或处理器架构的程序集的存放处。这是您的 Load() 的问题,您没有指定任何内容。 fusion 没有合理的方式为您选择组件,它很容易给您错误的组件。因此,即使只有一个可供选择,它也不会打扰。

需要指定完整的 AsssemblyName.FullName。使用 Project + Add Reference 来避免。

【讨论】:

    【解决方案2】:

    您应该使用完整的程序集限定名称加载它。

    【讨论】:

    • 我不想弄乱版本信息——我不在乎。那我该如何加载程序集呢?
    • 遗憾的是,如果它是一个签名程序集,您必须使用这个完整的程序集限定名称加载它。没门。想象一下,如果您将它安装在 GAC 中并且您有 2 或 3 个版本的相同程序集?当您在没有限定名称的情况下加载时会得到什么?我知道您宁愿避免使用版本信息,但是...? :D
    • 除非你使用 Assembly.LoadFrom - 但是你必须提供文件路径。
    • 是的,@ozczecho,你是对的。但我相信他的案例没有其他方法,他正在加载一个 Microsoft 程序集,该程序集将根据用户的机器安装在不同的位置,所以我不建议在这种情况下使用 LoadFrom。
    【解决方案3】:

    来自 MSDN 文档:

    // You must supply a valid fully qualified assembly name.            
            Assembly SampleAssembly = Assembly.Load
                ("SampleAssembly, Version=1.0.2004.0, Culture=neutral, PublicKeyToken=8744b20f8da049e3");
    

    【讨论】:

      【解决方案4】:

      Assembly.Load 的文档说您要提供程序集的完整名称(包括例如版本信息)。

      如果程序集通常从例如GAC。例如:

              try
              {
                  Assembly.Load("System");
              }
              catch (Exception ex)
              {
                  Console.WriteLine(ex.ToString());
              }
      
              Console.WriteLine(AppDomain.CurrentDomain.GetAssemblies().Any(
              assembly => assembly.FullName.StartsWith("System")));
              Console.ReadLine();
      

      表现出类似的行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-20
        • 1970-01-01
        相关资源
        最近更新 更多