использование ILMerge с библиотеками .NET 4
Две проблемы:
1) Основная assembly .NET не включена в сборку ILMerged Assembly
У меня возникли проблемы с использованием ILMerge в моей пост-сборке после обновления с .NET 3.5 / Visual Studio 2008 до .NET 4 / Visual Studio 2010. У меня есть решение с несколькими проектами, чья целевая структура установлена на «.NET Framework 4», , Я использую следующую команду ILMerge для объединения отдельных DLL проектов в одну DLL:
- Безопасно ли читать конец конца буфера на одной странице на x86 и x64?
- _addcarry_u64 и _addcarryx_u64 с MSVC и ICC
- Определить версию сборки (CLR) сборки
- Дополнительная информация о макете памяти исполняемой программы (процесса)
- Почему mulss занимает всего 3 цикла на Хасуэлле, отличном от таблиц инструкций Агнера?
if not $(ConfigurationName) == Debug if exist "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe" "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe" /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /keyfile:"$(SolutionDir)$(SolutionName).snk" /targetplatform:v4 /out:"$(SolutionDir)bin\development\$(SolutionName).dll" "$(SolutionDir)Connection\$(OutDir)Connection.dll" ...other project DLLs... /xmldocs
Если я перестану указывать расположение каталога платформы .NET 4, я получаю сообщение об ошибке «Неразрешенная ссылка на сборку: недопустимая: Система» от ILMerge. Если я не буду указывать местоположение каталога MSTest, я получаю сообщение об ошибке «Неразрешенная ссылка на сборку: ошибка Microsoft.VisualStudio.QualityTools.UnitTestFramework».
Команда ILMerge выше работает и создает DLL. Однако, когда я ссылаюсь на эту DLL в другом .NET .NET C #, и пытаюсь использовать код внутри нее, я получаю следующее предупреждение:
Основная ссылка «MyILMergedDLL» не может быть решена, поскольку она имеет косвенную зависимость от сборки .NET Framework «mscorlib, Version = 4.0, Culture = neutral, PublicKeyToken = b77a5c561934e089», которая имеет более высокую версию «4.0.65535.65535», чем версия «4.0.0.0» в текущей целевой структуре.
Если я /targetplatform:v4
флаг /targetplatform:v4
и попытаюсь использовать MyILMergedDLL.dll, я получаю следующую ошибку:
Тип «System.Xml.Serialization.IXmlSerializable» определен в сборке, на которую не ссылаются. Вы должны добавить ссылку на сборку «System.Xml, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089».
Кажется, я не должен был этого делать. Тот, кто использует мой MyILMergedDLL.dll API, не должен добавлять ссылки на любые библиотеки, на которые он ссылается. Как я могу обойти это?
2) Исключение TypeLoadException только при использовании объединенной сборки
Изменить: помимо этого, даже если я добавлю ссылку на System.Xml
в потребительском проекте, который использует MyILMergedDLL.dll, использование некоторого кода в MyILMergedDLL.dll дает это исключение:
System.TypeLoadException: Не удалось загрузить тип ‘System.Func`2’ из сборки ‘MyILMergedDLL, Version = 1.0.1.1, Culture = neutral, PublicKeyToken = …’.
Это код в моем потребительском проекте; строка, вызвавшая TypeLoadException
является второй:
var keys = new[] {"a", "b", "c"}; var row = new Row(keys);
Конкретный конструктор Row
который TypeLoadException
, определяется в открытом classе в MyILMergedDLL
, и когда я использую этот конструктор при ссылке на отдельные DLL проекта, он отлично работает. Только когда я использую этот конструктор при ссылке на объединенную DLL DL, я получаю исключение. Я не знаю, что происходит.
Вот этот конструктор:
public Row(IEnumerable keys) : base(keys) { }
И base
к которой он обращается, имеет этот код:
foreach (string key in keys.Where( key => !string.IsNullOrEmpty(key) )) { _dic.Add(key, string.Empty); }
- Как я могу просмотреть MSIL / CIL, сгенерированный компилятором C #? Почему это называется сборкой?
- Загрузка нескольких версий одной и той же сборки
- Размер сборки .NET влияет на производительность?
- C #: зачем подписывать сборку?
- Самый быстрый способ вычисления 128-битного целого по модулю 64-разрядного целого числа
- Как точно работает инструкция x86 LOOP?
- Maven: добавьте зависимость к банке относительным путем
- Сколько циклов процессора требуется для каждой инструкции сборки?
Недавно был выпущен выпуск для решения x64 проблем. Немедленно свяжитесь с Майком Барнеттом, если у вас все еще есть проблемы (mbarnett at microsoft dot com)
Добавление. Есть что-то очень, очень неправильное в вашей опции /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"
. Это вызвало множество проблем с программистами в последнее время после выхода .NET 4.5. Этот каталог не подходит для compilationов .NET 4.0. Его содержимое перезаписывается с помощью 4.5 сборок, вы больше не можете использовать его для установки .NET 4.0. Ошибка выполнения, которую вы получаете, очень неудобна, программа больше не может найти определенные типы. Обычно бомбардирует атрибут [Extension], иногда на интерфейсе ICommand.
Эти типы и некоторые другие были перемещены из одной сборки в другую. Использование правильных эталонных сборок – это твердое требование. Вы должны использовать:
/lib:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
Настройте в соответствии с вашей конкретной машиной и целевой версией рамы.
Вот «Post Build String» для Visual Studio 2010 с пакетом обновления 1 (SP1), используя .NET 4.0. Я создаю консоль .exe со всеми вложенными в нее суб-DLL-файлами.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(SolutionDir)\deploy\$(TargetFileName)" "$(TargetDir)$(TargetFileName)" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
Основные советы:
- Обратите внимание на каталог \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \
- Обратите внимание на каталог «ILMerge». Я скопировал утилиту ILMerge в свой каталог решений (чтобы я мог распространять исходный код, не беспокоясь о регистрации установки ILMerge).
Дополнительные советы:
Если у вас есть проблемы с неработоспособностью, добавьте «эхо» перед командой «Построить сборку». Затем откройте окно «Выход» в Visual Studio (View..Output) и проверьте точную команду, сгенерированную Visual Studio. В моем конкретном случае точная команда была:
"T:\PhiEngine\CSharp\ILMerge\ILMerge.exe" /out:"T:\PhiEngine\CSharp\Server Side\deploy\NfServiceDataHod.History.exe" "T:\PhiEngine\CSharp\Server Side\NfServiceDataHod\bin\Debug\NfServiceDataHod.History.exe" "T:\PhiEngine\CSharp\Server Side\NfServiceDataHod\bin\Debug\*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
Обновить
Добавлено это на мой шаг «Построение сборки», он заменяет все файлы .exe + .dll одним комбинированным .exe. Он также сохраняет неиспользуемый файл .pdb отладки:
rem Create a single .exe that combines the root .exe and all subassemblies. "$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards rem Remove all subassemblies. del *.dll rem Remove all .pdb files (except the new, combined pdb we just created). ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp" del *.pdb ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb" rem Delete the original, non-combined .exe. del "$(TargetDir)$(TargetName).exe" rem Rename the combined .exe and .pdb to the original name we started with. ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb" ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe" exit 0
Другие альтернативы:
- Объединение нескольких сборок в один EXE для приложения WPF .
- .Net Reactor .
- SmartAssembly (довольно дорогая коммерческая альтернатива).
Вы также можете добавить файл конфигурации со следующим:
Взято отсюда
Просто установите ссылки PresentationCore и PresentationFramework на «Копировать локальное = True» в окне свойств Visual Studio (после выбора ссылок в Обозревателе решений). Это решит проблему без жесткого кодирования каркасного пути. Я предпочитаю это решение, потому что путь отличается в зависимости от того, является ли сервер разработчика / сборки 64-битным или 32-битным и неизбежно изменится по мере выпуска новых версий .NET / VS.
Для тех, кто использует ILMerge из задач сообщества в .csproj:
У нас смешанный парк агентов построения CI, поэтому мы используем переменную среды $ (ProgramFiles) для указания правильного пути (папка с драйверами + x86 / x64), как это рекомендовала команда MSBuild .