Как определить дубликаты сборок? - PullRequest
0 голосов
/ 16 ноября 2009

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

Сценарий: Если у вас есть каталог с различными сборками .Net, которые называются по-разному, как вы сможете определить те, которые могут быть одинаковыми, но переименованы (т.е. копия MyAssembly.dll против MyAssembly.dll)?

Я могу думать о следующих пунктах:

  1. Проверить размер файла (должен быть одинаковым)

  2. Проверка номера версии сборки

  3. Выполните цикл сборки, используя Reflection, и попытайтесь найти любые различия.

Есть ли другой / более простой способ решения этой проблемы? Существуют ли другие критерии для определения того, являются ли 2 DLL-библиотеки с разными именами фактически одинаковыми скомпилированными сборками?

Ответы [ 3 ]

1 голос
/ 16 ноября 2009

Сначала я подумал, что вы можете использовать Equals или ReferenceEquals, чтобы сделать это, но это слишком подвержено ошибкам. Если вы используете Assembly.LoadFile, это не будет работать, например.

С помощью nUnit я провел следующие тесты, которые являются немного базовыми, но дают вам кое-что для продолжения. Необходим странный способ загрузки типов (см. MSDN). Я предполагаю, что вы знаете, как выполнять «быстрые тесты», если хотите проверить двоичное равенство и т. Д. (См. PS ниже).

Assembly asm1 = Assembly.LoadFile(@"someDebugAssembly.dll");
Assembly asm2 = Assembly.LoadFile(@"someReleaseAssembly.dll");

// load all the types (the double try/catch is on purpose)
Type[] types1 = null
Type[] types2 = null;
try
{
    types1 = asm1.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
    types1 = e.Types;
}
try 
{
    types2 = asm1.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
    types2 = e.Types;
}

// same length
Assert.AreEqual(types1.Length, types2.Length);

// check each type
IEnumerator types1Enumerator =  types1.GetEnumerator();
types1Enumerator.Reset();
foreach (Type t in types2)
{
    types1Enumerator.MoveNext();
    Assert.AreEqual(types1Enumerator.Current, t);
}

Примечание к коду: этот метод сравнения будет рассматривать две сборки как равные, если они содержат одинаковые типы. Это означает, что отладка и сборка выпуска, или другие версии, не принимаются во внимание. Используйте asm1.GetName() и его свойства (снова: не используйте Equals!) Для сравнения отдельных строк (версия, полное имя и т. Д.).

PS: было бы интересно определить, что составляет две равные сборки, т. Е .:

  1. они бинарные равны
  2. там версии и полные имена равны
  3. сильные имена равны
  4. все типы, глубоко сравниваемые, имеют одинаковые подписи

в зависимости от того, что вы выберете, две совершенно разные сборки (то есть отладочная сборка против сборочной версии) могут быть одинаковыми. Это действительно зависит от того, как вы хотите сравнить.

Обновление: исправлены предыдущие ошибки и добавлен пример кода

1 голос
/ 16 ноября 2009

Вы также можете использовать старую старую comp программу командной строки:

c:\tests> comp one.dll two.dll
Comparing one.dll and two.dll...
Files compare OK

Обновление: еще лучше. Загрузите средства поддержки Windows XP с пакетом обновления 2 , установите его (выберите Завершить установку ). Затем перейдите в диалоговое окно «Выполнить команду» и введите dupfinder . Укажите на нужную папку, и вы начнете сортировать все дубликаты в этом пути и его подпапках.

1 голос
/ 16 ноября 2009

Сначала я проведу простую быструю проверку с использованием пунктов 1. и 2. Это проверка размера файла и номера версии сборки. Если они все хорошо различаются, все готово.

Если нет, сохраните файлы с одинаковым размером / версией и вычислите их хэш MD5 / SHA1 / независимо от того, что вы предпочитаете. Если хэш-код одинаков, вы определенно находитесь в присутствии одной и той же сборки дважды. Поскольку сборки обычно не очень большие (не более нескольких мегабайт), хэш-вычисления должны быть достаточно быстрыми.

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