代码之家  ›  专栏  ›  技术社区  ›  Ian manuel aldana

我怎么知道“组件”是否真的发生了变化?

  •  7
  • Ian manuel aldana  · 技术社区  · 15 年前

    我在VS2005中创建了一个简单的“hello world”应用程序。它是一个直接向前的控制台应用程序;它只包含以下行:

    Console.WriteLine("Hello World");
    Console.ReadLine();
    

    当我尝试在不执行任何更改的情况下重建相同的控制台应用程序时(只需按“重建”按钮),我会得到一个稍微不同的可执行文件。(我从第一个和第二个生成的可执行文件生成了一个sha-1哈希,这是不同的!)

    当没有代码更改时,为什么会不同?到底发生了什么变化?我使用十六进制编辑器进行比较,只看到几个不同的字节。

    我想我的终极问题是,我怎么知道“装配”是否真的发生了变化?(当然,不需要查看文件版本、文件大小等)

    编辑

    到目前为止,我们已经确定差异在于PE头(时间戳和一些调试数据)。在我重新发明轮子之前,是否有一个“装配比较”工具忽略了PE头?

    谢谢, 伊恩

    3 回复  |  直到 15 年前
        1
  •  6
  •   Rup    15 年前

    差异将是

    • PE头中的时间戳
    • 调试数据的GUID(如果存在)

    (也许还有其他东西,根据你发布的其他输出?)要查看这些,请运行 dumpbin /all /rawdata:none 在vs命令提示符中的两个程序集上。

    要正确地做到这一点,您必须编写一个比较工具来理解这一点并忽略那些字节,或者复制可执行文件,清除时间戳和guid,然后比较这些版本。或者,在紧要关头,你可以使用 fc /b 正如controlfreak建议的那样,假设有20个字节不同(时间戳4个,guid 16个),那么它可能是相同的。

    使用清除时间戳的程序集(afaik)可能会有所帮助,它仅用于缓存其他dll中导出的符号偏移量(如果连接了该程序集),但可能更安全。如果您实际上需要二进制完全相同的程序集,我建议您更改您的进程,这样您就永远不会清理构建,除非您真的需要它。

        2
  •  2
  •   Dirk Vollmar    15 年前

    在Visual Studio命令提示下,可以进行更详细的比较:

    • 您可以使用 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        
      

      这个 /ALL 选项将转储DOS和PE头、CLR头、程序集元数据和已反汇编的IL。但是,它将不包含嵌入的资源。如果组件包含嵌入的资源,则可以使用 /OUT 选择权。这将为每个嵌入的资源创建一个单独的文件,您可以使用喜欢的diff工具(例如winmerge)进行比较:

      ildasm /ALL /TEXT /OUT:folder1\dump.txt folder1\assembly.dll
      ildasm /ALL /TEXT /OUT:folder2\dump.txt folder2\assembly.dll
      
        3
  •  0
  •   Matt Phillips    15 年前

    在命令行上 fc/b旧文件><新文件>