Руководство

Как сравнить два файла EXE или DLL на различия в ресурсах

Опубликовано

Когда что-то в выпущенной сборке выглядит неправильно, первым часто возникает вопрос: «какой ресурс изменился?» Возможно, иконка вернулась к старой версии, строка информации о версии устарела или при локализации незаметно пропала подпись пункта меню. Сравнивать два двоичных файла вручную долго, и легко ошибиться.

Resource Builder может сравнить ресурсы двух файлов EXE и DLL и показать, что именно добавлено, изменено или удалено, без ручной распаковки. В графическом интерфейсе то же сравнение охватывает также скомпилированные файлы .res, скрипты .rc и файлы .NET .resx / .resources; инструмент командной строки работает с собственными форматами. Типичные случаи использования:

  • Проверка регрессии перед выпуском: сравните новую сборку с последней заведомо рабочей.
  • Контроль качества локализации: убедитесь, что в переведённой сборке есть все строки и диалоги базовой сборки.
  • Аудит сторонней DLL: посмотрите, что на самом деле содержат её ресурсы и что изменилось между двумя её версиями.

Что можно сравнивать

Диалог Сравнить… в графическом интерфейсе сравнивает открытый проект с другим файлом на диске:

  • Если ваш проект — скрипт или файл собственных ресурсов, его можно сравнить с другим скриптом .rc, скомпилированным файлом .res или исполняемым файлом (.exe / .dll).
  • Если ваш проект — файл ресурсов .NET (.resx / .resources), его можно сравнить только с другим файлом .resx / .resources. Сравнение выявляет различия в однотипных наборах ресурсов с течением времени, а не между разными форматами, поэтому файл несовместимого типа отклоняется с понятным сообщением.

Сравнение всегда отражает текущее состояние проекта в памяти, включая несохранённые правки, а не только то, что было записано на диск в последний раз.

Сравнение ресурсов EXE и DLL в графическом интерфейсе

  1. Откройте файл, который вы считаете базовым, или файл, который проверяете. Открытым проектом может быть любая из сторон; сравнение показывает, что другой файл добавляет, изменяет или удаляет относительно него.
  2. Выберите Файл > Сравнить… или на ленте Проект > Импорт > Сравнить….
  3. Выберите другой файл в диалоге. Для .exe или .dll это просто сам двоичный файл, без шага извлечения.
Сравнение ресурсов EXE и DLL в Resource Builder
Сравнение ресурсов EXE и DLL в Resource Builder

Чтение результатов

Каждое различие выводится в списке и выделяется цветом как Добавлено, Изменено или Удалено:

  • Иконка или курсор с несколькими размерами отображается одной общей строкой, как и в основном дереве проекта, а не отдельной строкой для каждого размера.
  • При выборе строки старая и новая версии показываются рядом в областях просмотра, поэтому видно, чем именно они отличаются. Для изменённого набора STRINGTABLE просмотр показывает полный текст обеих версий.
  • Используйте переключатели фильтра и поле поиска, чтобы сузить список, а кнопки Отметить все / Снять все / Инвертировать / Все добавленные / Все изменённые — чтобы быстро выбрать строки.
Сравнение изменённого ресурса иконки
Сравнение изменённого ресурса иконки

Слияние различий обратно в проект

Отметьте нужные строки Добавлено и Изменено и нажмите Объединить:

  • Добавленные строки вставляются в проект как новые ресурсы.
  • Изменённые строки заменяют данные существующего ресурса на месте.
  • Удалённые строки носят только информационный характер и не имеют флажка. Слияние никогда ничего не удаляет из вашего проекта.

Поэтому сравнение полезно не только как проверка, но и как способ подтянуть изменения: если две сборки разошлись, вы можете перенести только изменившиеся ресурсы и не трогать остальное.

Особенность побайтового сравнения STRINGTABLE

Одному не стоит удивляться: если сравнивать с файлом, в котором ресурсы STRINGTABLE собраны другим компилятором или инструментом, набор может отображаться как Изменено на пару байт, хотя все строки в нём в области просмотра читаются одинаково. Разные компиляторы по-разному кодируют завершающий пустой слот в конце набора из 16 строк. Это не настоящее различие содержимого. Если нужна проверка в скрипте, разбирающая набор на отдельные строки, используйте параметр -parsestringtable инструмента командной строки, описанного ниже.

Сравнение из командной строки

То же сравнение выполняется без графического интерфейса:
sircc64.exe -diff file1 file2
Каждый из file1 и file2 может быть файлом .exe, .dll, .res или исходным файлом .rc. Выводится текстовый отчёт о различиях. -diff всегда принимает ровно два файла и не поддерживает маски.

Параметры:

Параметр

Действие

-ignoretype TYPE[,TYPE…]

Исключает из сравнения целые типы ресурсов. Принимает известные имена RT_* (ICON, BITMAP, VERSION, …) или буквальное имя пользовательского типа (PNG, SVG).

-nochanges

Пропускает сравнение содержимого. Сообщает только о добавленных и удалённых ресурсах, никогда об «изменённых».

-failmissing

Устанавливает код завершения 1, если какой-либо ресурс из file1 отсутствует в file2. В остальных случаях отчёт носит только информационный характер.

-parsestringtable

Дополнительно сравнивает отдельные строки внутри наборов STRINGTABLE , а не только хэш набора.

-failonmissingstring

Вместе с -parsestringtable устанавливает код завершения 1, если отдельная строка была удалена из набора.

Коды завершения: 0 — успех, 1 — ошибка, а для -diff также 1 при срабатывании -failmissing или -failonmissingstring.

Пример: остановить сборку, если пропали ресурсы

sircc64.exe -diff last-good\App.exe build\App.exe -failmissing -parsestringtable -failonmissingstring
if errorlevel 1 (
  echo Resource regression detected
  exit /b 1
)

Эта проверка проходит, только если в новой сборке есть все ресурсы и все записи таблицы строк, которые были в последней заведомо рабочей сборке. Подробнее о том, как встроить это в конвейер CI, включая сравнение с зафиксированным эталоном и вывод результатов в журнал сборки, рассказано в отдельной статье.

Попробуйте

Resource Builder — коммерческий продукт с бесплатным 30-дневным пробным периодом. Скачайте его на странице загрузки, откройте любую сборку и запустите Сравнить… с предыдущей версией.