3

我有一个与 Active Directory 对话以检索用户信息的服务器可执行文件。除了 AD,此 exe 还允许客户编写自己的插件来与自定义用户目录对话。

这个可执行文件是强命名的。

以下陈述是否属实:

为了让强命名程序集加载另一个程序集,加载的程序集也必须使用相同的密钥进行签名。

如果程序集没有经过强签名,则以下代码返回 null,并且没有错误表明程序集未正确签名。请注意,如果我签署程序集,我会得到一个 IService 实例。这让我相信加载的程序集必须是强签名的。

Assembly assembly = Assembly.LoadFrom(path);

foreach (Type t in assembly.GetTypes())
{
    if (t.GetInterface(typeof(IService).FullName) != null)
    {
      return (Activator.CreateInstance(t) as IService);
    }
}

那么,这是否意味着如果你有一个强签名的程序集,并且支持程序集插件,它们也必须被签名——插件编写者必须用相同的密钥对它们进行签名?这听起来不对。

最后,假设我有一个实现 IService 接口的程序集,但也引用了一个程序集,该程序集引用了另一个程序集,每个程序集都使用不同的密钥签名。当我尝试加载时会发生什么?它们都应该由同一个密钥签名吗?

4

3 回答 3

9

以下陈述是正确的:

为了让强命名程序集加载另一个程序集,加载的程序集也必须使用相同的密钥签名。

来自MSDN

如果强名称程序集随后引用了一个没有这些好处的简单名称的程序集,则您将失去使用强名称程序集所获得的好处并恢复为 DLL 冲突。因此,强名称程序集只能引用其他强名称程序集。


编辑:哦!尽管我的回答是正确的,正如 P Daddy 指出的那样,但这无关紧要!

使用反射加载弱命名程序集与引用程序集不同,并且不受相同方式的限制。

我使用以下程序集重新创建了您的代码(或至少是近似值):

  • Interface.dll签名,包含IService

  • Loader.exe签名的,一个控制台应用程序,它path使用你的代码加载并返回IService它在 that 指定的程序集中找到的第一个path,然后调用一个IService方法)

  • Plugin.dll未签名,包含IService实现)

接下来,我添加了对它的Plugin.dll引用Loaded.exe并尝试访问它的IService实现,但它按预期失败并显示以下消息:“程序集生成失败——引用的程序集'插件'没有强名称。”

最后,我运行控制台应用程序,将弱命名的名称传递给它Plugin.dll,它工作得很好。

似乎还有其他事情正在发生。Scott Hanselman 曾多次发表关于动态程序集加载变幻莫测的博客,他指向Suzanne Cook 的博客以获取有关该主题的权威细节。

于 2009-09-02T17:42:51.073 回答
2

如果你的装配强烈打字签名,我认为您加载的任何程序集也必须是强烈的打字签名...但不一定使用相同的密钥签名。

于 2009-09-02T17:41:26.910 回答
2

该声明是错误的 - 引用的程序集必须签名,但不一定使用相同的密钥。

当您引用强名称程序集时,您期望获得某些好处,例如版本控制和命名保护。如果强名称程序集随后引用了一个没有这些好处的简单名称的程序集,则您将失去使用强名称程序集所获得的好处并恢复为 DLL 冲突。因此,强名称程序集只能引用其他强名称程序集。

(取自MSDN 库

于 2009-09-02T17:42:28.813 回答