Можно ли объединить подмножество зависимостей с помощью ILMerge?

Я пытаюсь сделать что-то поисковое:

Скажем, у меня есть библиотека "coolproject", и она имеет зависимости от one.dll, two.dll и three.dll.

Я хотел бы использовать ILMerge для объединения coolproject с one.dll и two.dll, но NOT three.dll. По завершении слияния я должен иметь coolproject.dll и three.dll. Где бы я ни хотел использовать coolproject.dll, я должен также ссылаться на three.dll

Возможно ли это? Всякий раз, когда я пытаюсь, я получаю. Unresolved assembly reference not allowed: three. Я опускаю three.dll, установив "Копировать локаль" = false.

[EDIT]:

Выполняется следующим образом:

ILMerge /targetplatform:v2 /log /internalize /out:bin\coolproject.dll obj\Debug\coolproject.dll C:\Users\Nick\Projects\test\bin\one.dll C:\Users\Nick\Projects\test\bin\two.dll

Ответ 1

Причина, по которой это не работает, оказалась довольно простой: ILMerge должен иметь возможность найти DLL, которую вы пропустили из списка.

При оценке зависимостей в целевой библиотеке ILMerge по умолчанию проверяет различные местоположения для идентификации зависимой библиотеки (\ bin, GAC и т.д.), даже если вы ее не указали в списке командной строки. Если он не может найти эту библиотеку, вы должны указать ее местоположение, используя переключатель \lib. В противном случае вы увидите ошибку Unresolved assembly reference not allowed: three.

Пример:

ILMerge /lib:..\three\bin\three.dll /targetplatform:v2 /log /internalize /out:bin\coolproject.dll obj\Debug\coolproject.dll C:\Users\Nick\Projects\test\bin\one.dll C:\Users\Nick\Projects\test\bin\two.dll

Ответ 2

Я написал небольшой инструмент, чтобы справиться с этим.

Исходный код можно найти @https://github.com/leppie/ReferenceRemover.

В этом случае он будет использоваться как:

ReferenceRemover three.dll "(one|two).*" coolproject.dll

Объяснение аргументов:

  • Сборка для проверки
  • Regex соответствует ссылкам
  • Сборка, необходимая для перенаправления на

Выходной сигнал three.dll со скопированными его ссылками.

Ответ 3

Я думаю, что вы ищете параметр 'exclude' для переключателя /internalize. Например, если вы используете

/internalize:excludes.txt

где файл excludes.txt содержит

three.dll

он будет интернализировать one.dll и two.dll, но оставить three.dll в качестве внешней зависимости.

Вот несколько сообщений в блогах, которые подробно рассматриваются:

Обновление: Из документации:

2.10 ExcludeFile

public string ExcludeFile {get; задавать; }

Это свойство используется только в сочетании с свойством Internalize (раздел 2.12). Когда это задано перед вызовом Merge, он указывает путь и имя файла, которые будут использоваться для идентификации типов, которые не изменят видимость. Если Internalize is true, но ExcludeFile - это ", тогда все типы в любой сборке, отличной от первичной сборки, становятся непубличными. Установка этого свойства неявно устанавливает Internalize в true.

Содержимое файла должно быть одним регулярным выражением в строке. Синтаксис таков, что определен в пространстве имен .NET System.Text.RegularExpressions для регулярных выражений. Регулярные выражения сопоставляются с каждым полным именем типа, например," System.Collections.IList ". Если совпадение не выполнено, оно снова проверяется с именем сборки (в квадратных скобках), добавленным к типу имени. Таким образом, шаблон" [A]. * "Исключает все типы в сборке A из непубличных. (Обратные косые черты необходимы, потому что строка рассматривается как регулярное выражение.) Шаблон" N.T" будет соответствовать всем типам с именем T в пространстве имен N, независимо от того, в какой сборке они определены.

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

2.12 Интернализация

public bool Интернализация {get; задавать; }

Это означает, что изменения в видимой видимости изменяются для типов в сборках, отличных от первичной сборки. Когда это правда, тогда все неиспользуемые типы, которые видны вне их сборки, имеют видимость, измененную так, что они не видны снаружи объединенной сборки. Тип освобождается, если его полное имя соответствует строке из ExcludeFile (раздел 2.10) с использованием механизма регулярного выражения .NET.