Страницы

Поиск по вопросам

четверг, 11 октября 2018 г.

Можно ли добавить библиотеку в exe? [дубликат]

На данный вопрос уже ответили: Как скомпилировать все проекты солюшена в один .EXE? 3 ответа Я написал небольшой проект в VS 2013, используя стороннюю библиотеку (DLL). Теперь рядом с экзешником приходится постоянно держать эту библиотеку. Нельзя ли встроить эту библиотеку в проект или хотя бы необходимую часть кода, что бы не приходилось повсюду таскать эту dllку?


Ответ

Да, можно. Зависимую библиотеку можно встроить в ресурсы и подгружать оттуда вручную. Предполагается, что ваша библиотека уже находится в References проекта, проект собирается, программа успешно запускается.
Для начала добавьте в проект библиотеку как ресурс:
Меню Project -> Add Existing Item... - выбираете вашу сборку (dll, в диалоге открытия выберите тип файлов Executable Files). Библиотека появится в списке файлов проекта. Вызовите контекстное меню на добавленном файле, выберите Properties. Затем установите в открывшемся окне Build Actions -> Embedded Resource.
Добавьте в ваш проект следующий класс:
public static class Resolver { private static volatile bool _loaded;
public static void RegisterDependencyResolver() { if (!_loaded) { AppDomain.CurrentDomain.AssemblyResolve += OnResolve; _loaded = true; } }
private static Assembly OnResolve(object sender, ResolveEventArgs args) { Assembly execAssembly = Assembly.GetExecutingAssembly(); string resourceName = String.Format("{0}.{1}.dll", execAssembly.GetName().Name, new AssemblyName(args.Name).Name);
using (var stream = execAssembly.GetManifestResourceStream(resourceName)) { int read = 0, toRead = (int)stream.Length; byte[] data = new byte[toRead];
do { int n = stream.Read(data, read, data.Length - read); toRead -= n; read += n; } while (toRead > 0);
return Assembly.Load(data); } } }
Этот класс загрузит зависимую сборку из ресурса, как только основная программа обратится к ней, используя обработчик события AppDomain.AssemblyResolve
В классе, где находится точка входа программы, добавьте статический конструктор и вызовите метод RegisterDependencyResolver. Для примера, пусть у вас имеется консольное приложение:
class Program { static Program() { Resolver.RegisterDependencyResolver(); }
static void Main(string[] args) { // ... } }
Заботиться о выгрузке сборки не надо, т.к. это все равно невозможно (можно выгрузить только домен целиком).
Пример подсмотрен в книге Дж. Рихтера "CLR via C#".

Комментариев нет:

Отправить комментарий