Можно ли встроить уже существующую DLL в скомпилированный исполняемый файл C # (чтобы у вас был только один файл для распространения)? Если это возможно, как можно это сделать?
Обычно я просто оставляю DLL снаружи и заставляю программу установки справиться со всем, но на работе было несколько человек, которые спрашивали меня об этом, и я, честно говоря, не знаю.
Ответы:
Я настоятельно рекомендую использовать Costura.Fody - безусловно, лучший и самый простой способ встраивания ресурсов в вашу сборку. Это доступно как пакет NuGet.
После добавления его в проект он автоматически вставит все ссылки, скопированные в выходной каталог, в вашу основную сборку. Возможно, вы захотите очистить встроенные файлы, добавив цель в ваш проект:
Вы также сможете указать, включать ли pdb, исключать определенные сборки или извлекать сборки на лету. Насколько я знаю, поддерживаются и неуправляемые сборки.
Обновить
В настоящее время некоторые люди пытаются добавить поддержку DNX .
Обновление 2
Для самой последней версии Fody вам понадобится MSBuild 16 (Visual Studio 2019). Fody версии 4.2.1 будет делать MSBuild 15. (ссылка: Fody поддерживается только в MSBuild 16 и выше. Текущая версия: 15 )
источник
Просто щелкните правой кнопкой мыши свой проект в Visual Studio, выберите «Свойства проекта» -> «Ресурсы» -> «Добавить ресурс» -> «Добавить существующий файл»… и включите приведенный ниже код в файл App.xaml.cs или аналогичный.
Вот мой оригинальный пост в блоге: http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/
источник
bytes
является ли null, и если да, вернуть туда null. Вполне возможно, что dll не в ресурсах, в конце концов. Второе: это работает только в том случае, если сам этот класс не «использует» что-либо из этой сборки. Для инструментов командной строки мне пришлось переместить мой действительный программный код в новый файл и создать небольшую новую основную программу, которая просто делает это и затем вызывает исходную основную часть в старом классе..dll
имя содержит любые дефисы (т.е.twenty-two.dll
), они также будут заменены подчеркиванием (т.е.twenty_two.dll
). Вы можете изменить эту строку кода следующим образом:dllName = dllName.Replace(".", "_").Replace("-", "_");
Если они на самом деле являются управляемыми сборками, вы можете использовать ILMerge . Для собственных DLL у вас будет немного больше работы.
Смотрите также: Как можно объединить dll Windows C ++ в exe приложения C #?
источник
C++
по ссылке. ILMerge также очень легко работает для VB NET. Смотрите здесь https://github.com/dotnet/ILMerge . Спасибо @ Shog9Да, есть возможность объединить исполняемые файлы .NET с библиотеками. Есть несколько инструментов, доступных для выполнения работы:
Кроме того, это можно комбинировать с Mono Linker , который удаляет неиспользуемый код и, следовательно, делает полученную сборку меньше.
Другой возможностью является использование .NETZ , который не только позволяет сжимать сборку, но также может упаковать dll-файлы прямо в exe. Отличие от вышеупомянутых решений состоит в том, что .NETZ не объединяет их, они остаются отдельными сборками, но упакованы в один пакет.
источник
ILMerge может объединять сборки в одну сборку, если сборка содержит только управляемый код. Вы можете использовать приложение командной строки, или добавить ссылку на исполняемый файл и программно объединить. Для версии с графическим интерфейсом есть Eazfuscator , а также .Netz, которые бесплатны. Платные приложения включают BoxedApp и SmartAssembly .
Если вам нужно объединить сборки с неуправляемым кодом, я бы предложил SmartAssembly . У меня никогда не было икоты с SmartAssembly, но со всеми остальными. Здесь он может встраивать необходимые зависимости как ресурсы в ваш основной исполняемый файл.
Вы можете делать все это вручную, не беспокоясь о том, что сборка управляется или в смешанном режиме, встраивая dll в ваши ресурсы, а затем полагаясь на сборку AppDomain
ResolveHandler
. Это универсальное решение, принявшее наихудший вариант, то есть сборки с неуправляемым кодом.Ключевым моментом здесь является запись байтов в файл и загрузка из него. Чтобы избежать проблемы с курицей и яйцом, необходимо убедиться, что вы объявили обработчик перед доступом к сборке, и чтобы у вас не было доступа к элементам сборки (или к созданию экземпляров всего, что имеет отношение к сборке) внутри загрузочной (разрешающей сборку) детали. Также позаботьтесь о том, чтобы
GetMyApplicationSpecificPath()
не было никакого временного каталога, поскольку временные файлы можно было пытаться стереть другими программами или самостоятельно (не то, что он будет удален, когда ваша программа обращается к dll, но, по крайней мере, это неприятно. AppData хорош расположение). Также обратите внимание, что вы должны записывать байты каждый раз, вы не можете загрузить из местоположения только потому, что dll уже находится там.Для управляемых dll вам не нужно записывать байты, а непосредственно загружать из местоположения dll или просто читать байты и загружать сборку из памяти. Как это или так:
Если сборка полностью неуправляемая, вы можете увидеть эту ссылку или это о том, как загрузить такие библиотеки.
источник
Отрывок Джеффри Рихтера очень хорошо. Короче говоря, добавьте библиотеку как встроенные ресурсы и добавьте обратный вызов, прежде всего. Вот версия кода (найдена в комментариях на его странице), которую я поместил в начале метода Main для консольного приложения (просто убедитесь, что любые вызовы, использующие библиотеку, отличаются от метода Main).
источник
Чтобы расширить на @ ответ Бобби выше. Вы можете отредактировать ваш .csproj, чтобы использовать IL-Repack для автоматической упаковки всех файлов в одну сборку при сборке.
Install-Package ILRepack.MSBuild.Task
Вот простой пример, который объединяет ExampleAssemblyToMerge.dll в выходные данные вашего проекта.
источник
Вы можете добавить библиотеки DLL в качестве встроенных ресурсов, а затем при запуске программы распаковать их в каталог приложения (после проверки, чтобы убедиться, что они там уже есть).
Установочные файлы настолько просты в создании, что я не думаю, что это того стоит.
РЕДАКТИРОВАТЬ: Этот метод будет легко с сборками .NET. С не-.NET DLL было бы намного больше работы (вам нужно было бы выяснить, где распаковать файлы, зарегистрировать их и так далее).
источник
Другим продуктом, который может справиться с этим элегантно, является SmartAssembly, на SmartAssembly.com . Этот продукт, в дополнение к объединению всех зависимостей в одну DLL, (необязательно) запутывает ваш код, удаляет дополнительные метаданные, чтобы уменьшить размер получаемого файла, а также может фактически оптимизировать IL для повышения производительности во время выполнения.
Существует также некоторая глобальная функция обработки исключений / отчетности, которую она добавляет к вашему программному обеспечению (при желании), которая может быть полезной. Я считаю, что он также имеет API командной строки, поэтому вы можете сделать его частью вашего процесса сборки.
источник
Ни подход ILMerge, ни обработка события AssemblyResolve Ларсом Холмом Дженсеном не будут работать для хоста плагина. Например, исполняемый файл H загружает сборку P динамически и обращается к ней через IP- интерфейс, определенный в отдельной сборке. Чтобы встроить IP в H , нужно немного изменить код Ларса:
Хитрость в обработке повторяющихся попыток разрешить одну и ту же сборку и вернуть существующую вместо создания нового экземпляра.
РЕДАКТИРОВАТЬ: Чтобы это не испортило сериализацию .NET, убедитесь, что возвращено значение null для всех сборок, не встроенных в вашу, таким образом, по умолчанию используется стандартное поведение. Вы можете получить список этих библиотек:
и просто вернуть ноль, если переданная сборка не принадлежит
IncludedAssemblies
.источник
.NET Core 3.0 изначально поддерживает компиляцию в один .exe
Эта функция включена с помощью следующего свойства в файле проекта (.csproj):
Это делается без какого-либо внешнего инструмента.
Смотрите мой ответ на этот вопрос для получения дополнительной информации.
источник
Это может показаться упрощенным, но WinRar дает возможность сжать кучу файлов в самораспаковывающийся исполняемый файл.
Он имеет множество настраиваемых опций: конечный значок, извлечение файлов по заданному пути, файл для выполнения после извлечения, настраиваемый логотип / текст для всплывающего окна, отображаемого во время извлечения, вообще без всплывающего окна, текст лицензионного соглашения и т
. Д. Может быть полезно в некоторых случаях ,
источник
Я использую компилятор csc.exe, вызываемый из скрипта .vbs.
В вашем скрипте xyz.cs добавьте следующие строки после директив (мой пример для Renci SSH):
Теги ref, res и ico будут выбраны сценарием .vbs ниже для формирования команды csc.
Затем добавьте вызывающего преобразователя сборок в Main:
... и добавить сам преобразователь где-нибудь в классе:
Я называю скрипт vbs для соответствия имени файла .cs (например, ssh.vbs ищет файл ssh.cs); это делает запуск сценария во много раз намного проще, но если вы не такой идиот, как я, то универсальный сценарий может выбрать целевой файл .cs из перетаскивания:
источник
Возможно, но не все так просто, создать гибридную нативную / управляемую сборку в C #. Если бы вы использовали C ++, это было бы намного проще, поскольку компилятор Visual C ++ может создавать гибридные сборки так же легко, как и все остальное.
Если у вас нет строгих требований к созданию гибридной сборки, я согласен с MusiGenesis, что на самом деле это не стоит того, чтобы делать с C #. Если вам нужно сделать это, возможно, обратите внимание на переход на C ++ / CLI.
источник
Как правило, вам понадобится инструмент для пост-сборки, чтобы выполнить слияние сборки, как вы описываете. Существует бесплатный инструмент под названием Eazfuscator (eazfuscator.blogspot.com/), предназначенный для манипулирования байт-кодом, который также обрабатывает объединение сборок. Вы можете добавить это в командную строку после сборки с помощью Visual Studio для объединения ваших сборок, но ваш пробег будет отличаться из-за проблем, которые могут возникнуть в любых сценариях слияния нетривиальных сборок.
Вы также можете проверить, имеет ли сборка до тех пор, пока NANT не сможет объединять сборки после сборки, но я сам не достаточно знаком с NANT, чтобы сказать, встроена ли функциональность или нет.
Существует также множество плагинов Visual Studio, которые выполняют слияние сборок как часть сборки приложения.
В качестве альтернативы, если вам не нужно, чтобы это делалось автоматически, есть ряд инструментов, таких как ILMerge, которые объединят сборки .net в один файл.
Самая большая проблема, с которой я столкнулся при объединении сборок, заключается в том, используют ли они какие-либо похожие пространства имен. Или, что еще хуже, ссылаются на разные версии одной и той же библиотеки DLL (мои проблемы были, как правило, с файлами DLL NUnit).
источник