Как я могу узнать, действительно ли изменилась сборка? - PullRequest
7 голосов
/ 23 июля 2010

Я создал простое приложение "Hello World" в VS2005. Это простое консольное приложение; он содержит только следующие строки:

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

Когда я пытался пересобрать одно и то же консольное приложение БЕЗ внесения каких-либо изменений (просто нажмите кнопку перестройки), я получаю слегка другой исполняемый файл. (Я сгенерировал хеш SHA-1 из 1-го и 2-го сгенерированных исполняемых файлов, и он отличается!)

Почему отличается, когда нет изменений кода? Что на самом деле изменилось? Я использовал шестнадцатеричный редактор для сравнения и видел только пару разных байтов.

Полагаю, мой последний вопрос: как я могу узнать, действительно ли изменилась "сборка"? (Конечно, не смотря на версии файлов, размер файлов и т. Д.)

EDIT

Пока что мы установили, что разница заключается в PE-заголовке (отметка времени и некоторые данные отладки). Прежде чем я заново изобрел колесо, есть ли инструмент «сравнения сборки», который игнорирует PE-заголовок?

Спасибо, Ian

Ответы [ 3 ]

6 голосов
/ 23 июля 2010

Различия будут

  • отметка времени в заголовке PE
  • GUID отладочных данных, если имеется

(и, может быть, что-то еще, согласно другим выводам, которые вы опубликовали?) Чтобы увидеть их, запустите dumpbin /all /rawdata:none для обеих сборок в командной строке VS.

Чтобы сделать это правильно, вам нужно написать инструмент сравнения, который бы это понимал и игнорировал эти байты - или брал копии исполняемых файлов, очищал метку времени и GUID, а затем сравнивал эти версии. Или, в крайнем случае, вы могли бы использовать что-то вроде fc /b, как подсказывает controlfreak, и предположить, что если <20 байтов отличаются (4 для метки времени, 16 для GUID), то это, вероятно, то же самое. </p>

Вы можете с легкостью избежать использования сборки с очищенной отметкой времени - AFAIK она используется только для кэширования экспортированных смещений символов в других библиотеках DLL, если вы подключите их, но, вероятно, безопаснее оставить все как есть. Если вам действительно нужны двоичные идентичные сборки, я предлагаю вам изменить процессы, чтобы вы никогда не выполняли чистую сборку, если вам это действительно не нужно.

2 голосов
/ 23 июля 2010

Из командной строки 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        
    

    Опция /ALL сбросит заголовки DOS и PE,Заголовок CLR, метаданные сборки и разобранный IL.Однако он не будет содержать встроенные ресурсы.Если ваша сборка содержит встроенные ресурсы, вы можете использовать опцию /OUT.Это создаст отдельный файл для каждого встроенного ресурса, который вы можете сравнить, используя ваш любимый инструмент сравнения, например WinMerge:

    ildasm /ALL /TEXT /OUT:folder1\dump.txt folder1\assembly.dll
    ildasm /ALL /TEXT /OUT:folder2\dump.txt folder2\assembly.dll
    
0 голосов
/ 23 июля 2010

в командной строке fc / b <старый файл> <новый файл>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...