为什么相同代码和相同 .net 框架版本生成的 .net dll 不是二进制一致的?

4
我有一个C#项目,编译在不同的机器上会生成不同的dll文件。所以我的问题是为什么生成的dll文件不同?是否有方法可以在不同的机器上生成完全相同的dll文件?
编辑:我正在尝试做的是,多个客户端从服务器获取一些代码片段并进行编译。在dll编译后,它在客户端上被反复使用。如果我能够在所有机器上生成相同的DLL,则可以使用加密哈希轻松检查客户端上的DLL是否被篡改。
由于某些原因,代码必须在客户端机器上编译。因此,数字签名不是一个选项。

为什么需要二进制相同的库?同时了解涉及的两台机器的确切配置、操作系统、.NET版本、使用的IDE或编译器也是很好的。 - Bobby
也许这两个项目设置了不同的程序集信息?例如 GUID。 - Steven Jeuris
机器的配置或编译设置显然有某种不同。它们有多大的不同?.net程序集可以包含构建版本信息 - 这是唯一的区别吗? - James Gaunt
@Bobby:配置相同。 - Babar
1
@Steven Jeuris:差异在文件的开头和结尾处。此外,不同的字节数量很少。 - Babar
显示剩余5条评论
1个回答

5
您不能期望重建的任何文件二进制完全一致——尤其是程序集。所有包括数据创建日期和修改日期在内的文档元数据都会不同。
如果您需要进行比较,您需要对程序集进行签名(强命名),并比较公钥令牌以及程序集版本号。

更新

您所做的事情容易引起麻烦,但我也能理解这种情况有时必须要做。如果我是您,我会在服务器上编译二进制文件,并让客户端下载二进制文件而不是代码。毕竟,客户端可能没有C#编译器。
回答您的问题,如果您坚持在客户端上编译,请每次编译时创建本地哈希值并存储在注册表、某个文件等位置,然后再进行比较。

更新2

C#编译器从未保证它将创建相同的二进制文件。在编译时,许多东西都会被创建,例如匿名函数的命名、自动属性的支撑值、匿名方法、内部GUID等等......所有这些都将在编译时创建,虽然编译器使用的命名约定通常会导致名称最终相同,但无法保证

是的,代码签名是适当的解决方案。机器的配置是无关紧要的。你必须使用正确的工具来解决手头的问题。 - Cody Gray
我已经更新了问题并添加了有关情境的详细信息。由于某些原因,代码必须在客户机上编译。因此数字签名不是一个选项。 - Babar
1
是的,我太傻了 - 我的意思是文档属性,例如媒体文件或办公文档中的属性。我会更新我的回答... - Aliostad
+1:我刚刚比较了一些二进制文件,并注意到更新2中提到的行为。此外,在构建调试版本时,我还遇到了一些更多的变化。 - Steven Jeuris
更具体地说,当启用pdb时,在编译的代码中会出现不同的“WrapNonExceptionThrows”。这在发布版本中也是默认启用的。我注意到由于使用LINQ而导致了匿名类型。 - Steven Jeuris
显示剩余4条评论

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