【问题标题】:How is an assembly resolved in .NET?如何在 .NET 中解析程序集?
【发布时间】:2015-05-14 16:40:15
【问题描述】:

如何在 .NET 中解析程序集。我的意思是,如何解析具有完全限定名称的程序集。我对公钥/私钥令牌和强命名感到困惑。谢谢

编辑:我还阅读了有关延迟签名之类的信息。人们真的会使用它吗? (有没有人实际使用过延迟签名)谁生成了对程序集进行签名的密钥。如果我问的问题太多,我很抱歉。但是,我对这整件事感到困惑。

【问题讨论】:

    标签: .net assembly-resolution


    【解决方案1】:

    强命名与“公钥令牌”一起使用以生成程序集完整显示名称 (mscorlib, version=2.0.0.0, Culture=neutral, PublicKeyToken=b4778,.....)。这使我们能够在同一个应用程序目录中同时拥有同一个程序集的多个版本。

    公钥令牌(因此,字符串命名技术)还允许 .NET 加载程序检测自您分发程序集内容以来是否有人篡改了它。这是真的,因为当您使用“私有令牌”签署程序集时,编译器将生成一个哈希值,该哈希值嵌入到描述“私有令牌”的公共部分的程序集元数据中。然后,加载程序可以使用此值来确定您的程序集是否被修改。

    关于解决程序集,有一些基本的事情需要考虑:

    • 探测 加载器尝试使用基本目录“探测”技术来定位程序集。这意味着它将尝试在应用程序的启动目录中找到“MyAssembly.dll”(例如),如果不存在,则在该目录下的子目录中。如果探测未能找到“MyAssembly.dll”,则触发AppDomainAssemblyResolve 事件。

    • 机器/用户/系统配置 machine.configuser.configsystem.config 是存储在系统本地的配置文件,可用于更改“机器”、“用户”或“系统”范围设置上的程序集解析器的行为。

    • 发布商政策 可以使用应用程序配置文件中的“<assemblyIdentity>”XML 标记(例如,“MyApp.exe.config”)将解析器指向某个版本的程序集或从其他位置加载程序集。

    • 自定义分辨率 处理AppDomain 的“AssemblyResolve”事件。每当无法通过“传统”方法解决程序集时,就会引发此事件

    到目前为止,最简单的机制是处理“AssemblyResolve”事件。

    总而言之,解析器在当前目录或全局程序集缓存中查找,处理策略,然后最终允许自定义解析。

    【讨论】:

    • “允许 .NET 加载程序检测是否有人篡改了您的程序集内容...”不太明白。
    • 当然。基本上,当您使用强名称哈希值(您也可以使用命令行实用程序 sn.exe)编译程序集时,哈希值将写入程序集的元数据,描述其版本、文化、名称和令牌值。当加载器加载您的程序集时,它会检查您的程序集是否具有公钥令牌,如果有,则对您的程序集运行相同的哈希算法,将其与程序集元数据中的内容进行比较,如果它们不同,则拒绝加载程序集。这就是加载检测“篡改”的方式。如您所见,它非常有限,但现在足够了。
    • 从表面上看,它看起来像是一种保护我们的 .NET 代码的方法。但遗憾的是,兴奋很快消退,您很快就会意识到混淆是次要的。
    • 而且我没有得到“..它看起来像是保护我们的 .NET 代码的一种方式”的部分。我一直认为签署程序集可以确保我们使用的是最初打算使用的程序集。 (但是有没有可能失败的情况?)而不是为了保护源代码(为此目的是混淆)。
    • 是的,签名确实确保我们只加载我们构建的程序集(它还允许并行版本控制并通过全局程序集缓存在全球范围内共享我们的程序集)。此外,发布者策略允许我们将引用从程序集的一个版本“重定向”到不同的版本。有没有会失败的情况?当然。但如果引用的程序集加载失败,通常与路径位置、程序集版本无效或安全权限问题(如从共享网络驱动器加载)有关。
    【解决方案2】:

    MSDN 上的以下文章应该可以帮助您:

    http://msdn.microsoft.com/en-us/library/yx7xezcf(VS.71).aspx

    .NET 中的程序集解析可能相当复杂,因为程序集可以位于各种位置,包括 GAC、与执行程序集位于同一位置、影子复制等。一般过程称为 Fusion 过程,并确保加载程序集时满足适当的安全措施。

    【讨论】:

      【解决方案3】:

      程序集解析可能涉及多个步骤,具体取决于它尝试加载的程序集的位置(GAC、应用程序基础文件夹、子文件夹或远离您的基础应用程序文件夹的其他文件夹)。

      这是一篇关于如何指定 .Net 查找程序集的好文章。 MSDN Article

      如果您希望运行时解析未存储在应用程序基础文件夹或 GAC 中的程序集,则需要注册 AppDomain 事件,该事件在找不到程序集时引发。然后,您将通过检查文件是否存在于您的其他位置来对该事件做出反应,然后使用 Assembly.LoadFrom(thePath) 将其返回。

      进一步添加到这个答案是这个破解链接应该很好地总结了整个强命名与键:Strong Naming - keys etc..

      对此有任何问题,尽管问!

      【讨论】:

      • 谁生成签署程序集的密钥?
      猜你喜欢
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 2013-09-09
      • 2021-06-04
      • 2018-05-05
      • 1970-01-01
      • 2011-07-05
      相关资源
      最近更新 更多