C# 我怎样才能知道;“装配”;真的改变了吗?
我在VS2005中创建了一个简单的“Hello World”应用程序。这是一个直接的控制台应用程序;它只包含以下行:C# 我怎样才能知道;“装配”;真的改变了吗?,c#,comparison,file-comparison,C#,Comparison,File Comparison,我在VS2005中创建了一个简单的“Hello World”应用程序。这是一个直接的控制台应用程序;它只包含以下行: Console.WriteLine("Hello World"); Console.ReadLine(); 当我尝试在不执行任何更改的情况下重建同一个控制台应用程序时(只需按rebuild按钮),我得到了一个微妙不同的可执行文件。(我从第一个和第二个生成的可执行文件生成了一个SHA-1哈希,这是不同的!) 为什么在没有代码更改的情况下会有所不同?到底发生了什么变化?我使用十六进
Console.WriteLine("Hello World");
Console.ReadLine();
当我尝试在不执行任何更改的情况下重建同一个控制台应用程序时(只需按rebuild按钮),我得到了一个微妙不同的可执行文件。(我从第一个和第二个生成的可执行文件生成了一个SHA-1哈希,这是不同的!)
为什么在没有代码更改的情况下会有所不同?到底发生了什么变化?我使用十六进制编辑器进行比较,只看到了几个不同的字节
我想我的最终问题是,我如何知道“程序集”是否真的发生了变化?(当然不看文件版本、文件大小等)
编辑
到目前为止,我们已经确定差异在于PE头(时间戳和一些调试数据)。在我重新发明轮子之前,有没有忽略PE标题的“组装比较”工具
谢谢,
命令行上的Ian
fc/b
- PE头中的时间戳
- 调试数据的GUID(如果存在)
dumpbin/all/rawdata:none
要正确地执行此操作,您必须编写一个比较工具,该工具理解这一点并忽略这些字节,或者复制可执行文件,清除时间戳和GUID,然后比较这些版本。或者,在紧要关头,您可以像controlfreak建议的那样使用fc/b
,并假设如果有<20个字节不同(时间戳为4个字节,GUID为16个字节),则可能是相同的
使用清除了时间戳的程序集很可能会得逞——如果您连接了它,它只用于在其他DLL中缓存导出的符号偏移量——但保持原样可能更安全。如果您确实需要二进制完全相同的程序集,我建议您更改流程,这样您就永远不会清理生成,除非您确实需要它。在Visual Studio命令提示符下,您可以进行更详细的比较:
- 您可以使用
的输出来比较PE头:dumpbin
dumpbin /HEADERS assembly.dll
- 或者,您可以使用
比较PE头和程序集中嵌入的IL代码:ildasm
ildasm /ALL /TEXT assembly1.dll > dump1.txt ildasm /ALL /TEXT assembly2.dll > dump2.txt fc dump1.txt dump2.txt
选项将转储DOS和PE头、CLR头、程序集元数据和反汇编IL。但是,它将不包含嵌入式资源。如果您的组件包含嵌入式资源,则可以使用/ALL
选项。这将为每个嵌入式资源创建一个单独的文件,您可以使用自己喜欢的diff工具(例如WinMerge:/OUT
ildasm /ALL /TEXT /OUT:folder1\dump.txt folder1\assembly.dll ildasm /ALL /TEXT /OUT:folder2\dump.txt folder2\assembly.dll
vsvars32
),在两个文件上运行dumpbin/all/rawdata:none
,然后windiff输出。第一个是时间戳,我猜其中一个是调试GUID,但我不知道第三个是什么。为了正确忽略这些字节,我需要知道这些字节的位置和范围,对吗?是否有某种文档我可以阅读?这里是MSDN的PE格式文档链接:我指的是COFF头中的时间戳和调试目录的内容。然而,如果做这件事的工具还不存在的话,我会非常惊讶——但我不知道有一个,对不起。哇,你搞定了。它是时间戳和一些调试数据!4C4953A4时间戳Fri Jul 23 16:32:36 2010 4C4953A4 cv 6D 000026E4 8E4格式:RSDS,{F42126D-98D4-4D76-B70D-9C3E398E5426},1,C:\HelloWorld\HelloWorld\obj\x86\Debug\HelloWorld.pdb*使用dumpbin/all/rawdata:none