использование 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:

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); } 

Недавно был выпущен выпуск для решения 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 .

  • Медленная инструкция jmp
  • Как ссылаться на сборки .NET с помощью PowerShell
  • В чем разница между MOV и LEA?
  • Visual Studio 2010 не создает перед запуском при изменении кода
  • Цикл с вызовом функции быстрее, чем пустой цикл
  • Что регистрирует сохранение в соглашении вызова ARM C?
  • C # компиляция для 32/64 бит или для любого процессора?
  • Использование разных версий одной и той же сборки в одной папке
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • Как использовать строки в emu8086
  • Сделать муравей тихий без флага -q?
  • Interesting Posts

    Проблемы с записью дисков bluray

    Порт Ethernet на ThinkPad не подключается, но тот, что на ультрабазе (док-станция)

    Полезно ли использовать целочисленный столбец для хранения почтовых индексов США в базе данных?

    В Excel 2010, как я могу создать шаблон с функцией, автоматически заканчивается в последней ячейке с данными?

    MongoDB – Ошибка: команда getMore не выполнена: курсор не найден

    Systemctl enable отличается от systemctl start, как?

    Как повторить fragment HTML несколько раз без ngFor и без другого @Component

    Использует ли атрибут Spring @Transactional собственный метод?

    Нелегко реализовать простой синглтон в быстрой

    Excel VBA Performance – 1 миллион строк – удаление строк, содержащих значение, менее чем за 1 минуту

    Отключить кнопки в jQuery Mobile

    Пользовательский макет пользовательского интерфейса Android ProgressBar

    Как включить восстановление пакета NuGet в Visual Studio?

    Как выбрать целые слова в режиме мыши Tmux?

    Поддержка JAX-RS Jersey 2.10 в Websphere 8

    Давайте будем гением компьютера.