如何在保留程序集元数据的情况下,对外部DLL文件进行强命名签名?

6

我有一些在我的项目中使用的未签名库。因为我的应用程序是强制签名的,所以这些库也必须被签名。

我使用以下方式对这些库进行签名:

"%PROGRAMFILES%\Microsoft SDKs\Windows\v7.1\Bin\ildasm.exe" /nobar /all /out=library.il library.dll
"%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ilasm.exe" /dll /key=MyKey.snk library.il

问题在于任何元数据,如版本号,在现在已签名的DLL中丢失。这是一个问题,因为现在一些库之间的依赖关系被破坏了。我如何保留版本号而不必实际编译这些库的源代码呢?
更新:
实际上,有一个特定的DLL显示出这个问题,我发现它是使用ILMerge构建的。也许这是造成问题的原因。只是为了明确:由ILMerge生成的DLL确实具有适当的元数据,但在反汇编和重新组合后,元数据就会消失。
更新2:
我在Reflector中打开了这个DLL,似乎至少版本号还在。我一直在使用Windows资源管理器的文件属性对话框/详细选项卡进行检查。所以我认为缺少的是清单。
2个回答

4
我想知道为什么会发生这种情况。我在使用ilasm和ildasm对未签名和已签名的程序集进行往返编译方面有相当不错的经验。您能否验证ILasm生成的元数据是否仍包含版本信息(程序集范围底部):
.assembly ConsoleApplication1
{
  //...
  .hash algorithm 0x00008004
  .ver 1:0:0:0
} 

我再次检查了一下,它在我的电脑上“能够正常工作”(使用与您相同的命令行开关)。

实际上会丢失的是FileVersion属性(当悬停在程序集上时在Windows资源管理器中看到的属性)。AssemblyVersion属性仍然存在且正确。您是否混淆了这两个属性?只有AssemblyVersion对于绑定信息很重要。有关更多信息,请参见此SO帖子

希望我能帮到您,否则您需要提供更多上下文。


我又在隔离的环境中尝试了一次,发现所有元数据都不见了。在生成的 IL 文件中,像你建议的那样,在程序集作用域底部可以看到版本号。与此同时,我意识到这个特定的 DLL 是使用 ILMerge 构建的,可能导致了问题。 - Sandor Drieënhuizen
你检查过ILMerge的输出了吗?基本上,我无法想象在此之前程序集发生了什么,如果程序集版本存在于ildasms输出中,ilasm应该能够正确处理它。 - Johannes Rudolph
我在 Reflector 中打开了 DLL,至少版本号还在。我一直在使用 Windows Explorer 的文件属性对话框/详细信息选项卡进行检查。因此,我认为缺少的是清单。这不应该对程序集绑定产生任何影响,对吧? - Sandor Drieënhuizen
不,只要 AssemblyVersion 仍然存在,你应该没问题。很高兴能帮到你。 - Johannes Rudolph

1

如果您有源代码,那么只需使用强名称重新编译库-反汇编和重新组合通常效果很好,但仍然是一种黑客行为。

为了使库之间的依赖关系正常工作,您需要更新.il代码中的引用,以使用它们所引用的程序集的公钥,否则它们将尝试引用未签名的程序集,从而在运行时无法加载它。

您可以手动完成此操作,但在处理2或3个程序集后,这会变得非常繁琐。解决此问题的快速方法是signer,它可以为您处理许多涉及的困难,并且表现出色-通常非常快速和干净。

(请注意,目前它已构建针对旧版.NET版本。如果您使用C# 4 / .NET 4程序集,则需要下载源代码,将其更改为目标.NET 4并重新构建它,以获取一个正确处理.NET 4程序集的signer.exe)。


在我的情况下,我正在运行一个脚本,该脚本下载几个相互依赖的库的最新源代码,并按正确顺序编译它们,通过刚刚编译的DLLs。这应该可以避免您所描述的关于引用不匹配的问题。顺便说一句,感谢您指出Signer,看起来非常有趣。我会试一试。 - Sandor Drieënhuizen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接