На данный вопрос уже ответили: Как скомпилировать все проекты солюшена в один .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#".
Комментариев нет:
Отправить комментарий