Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 65, средняя оценка - 4.66
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
#1

Включение dll внутрь exe - C#

31.05.2013, 19:46. Просмотров 14974. Ответов 17

как подключить управляемую библиотеку, при этом включив ее сразу в exe, чтобы не пришлось ее таскать вслед за exe? Можно ли это сделать без ILmerge? Как?

http://www.cyberforum.ru/csharp-beginners/thread1347458.html

0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.05.2013, 19:46
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Включение dll внутрь exe (C#):

Упаковать exe и dll в один exe файл
Добрый день! Для защиты использую IlProtector. На выходе получается exe и 2...

Запуск Load.dll (бывшая Load.exe) в дереве проц-ов, Как запустить прогой на C# .dll-ку
Подскажите, как должен выглядеть код простейшей программы на C# (Loader.exe),...

Dll to exe
Здравствуйте,помогите новичку который не понимает как сделать данное дело....

exe=>dll
у меня имееться обычный проект на си шарпе как из него сделать dll -ку...

Переменные из dll в exe
Здравствуйте вот уже сколько мучаюсь извлечением переменных из dll Помогите....

17
Conrad
31 / 31 / 4
Регистрация: 26.02.2011
Сообщений: 83
31.05.2013, 19:59 #2
Правой кнопкой по проекту Visual Studio, выбираешь Project Properties -> Resources -> Add Resource -> Add Existing File… И добавляешь следующий код в App.xaml.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
 
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");
 
    dllName = dllName.Replace(".", "_");
 
    if (dllName.EndsWith("_resources")) return null;
 
    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
 
    byte[] bytes = (byte[])rm.GetObject(dllName);
 
    return System.Reflection.Assembly.Load(bytes);
}
2
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
31.05.2013, 20:05  [ТС] #3
спасибо, а как же потом к этой библиотеке обращаться? using надо ведь использовать, или это если только есть ссылка?
А в свойствах файла что-нибудь менять?
0
beats
100 / 38 / 9
Регистрация: 09.12.2012
Сообщений: 567
31.05.2013, 20:34 #4
да в ресурсы с типом разное добавляешь ее, потом в byte[] переменную считываешь и создаешь файл из этой переменной, а обращение по пути. при закрытии проги можно удалить
1
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
31.05.2013, 20:58  [ТС] #5
аааа ладно, попробуем

Добавлено через 17 минут
а что за App.xaml.cs?
0
phantom96
MЫW
124 / 109 / 9
Регистрация: 15.02.2013
Сообщений: 538
31.05.2013, 21:33 #6
В винформах Program.cs
1
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
01.06.2013, 12:08  [ТС] #7
а как создавать типы из библиотеки?

Добавлено через 6 минут
Мне же придется проделывать GetType() для каждого типа, который я захочу использовать? А можно ли создавать типы из такой библиотеки непосредственно, как если бы она была объявлена в ссылках?

Добавлено через 5 минут
а методы придется инвокать? Как это отразится на производительности?
0
kill4you
0 / 0 / 0
Регистрация: 01.06.2013
Сообщений: 11
01.06.2013, 13:50 #8
Выгрузил либу рядом с программой и заюзал, в чем проблема то?
0
Dexiny
170 / 87 / 10
Регистрация: 27.05.2013
Сообщений: 290
01.06.2013, 14:14 #9
Лучший ответ Сообщение было отмечено как решение

Решение

Ох и насоветуют. Не надо никаких GetType(), если библиотека managed.

1)Добавляем библиотеку в References. В Solution Explorer (колонка с файлами справа) правой кнопкой мыши по References - выбираем "Add Reference...", вкладка Browse, выбираем dll, ОК.
2)Открываем список References всё в том же Solution Explorer (просто клик левой кнопкой мыши), находим нашу подключенную библиотеку. Кликаем правой кнопкой мыши и выбираем Properties. Устанавливаем параметр "Copy Local" в False. Всё теперь в коде пишем using MyDll; и пользуемся классами библиотеки.
3)Добавляем в ресурсы файл *.dll. В меню Project > Properties > Resources > жмакаем Add Resource > выбираем снова нашу длл (либо сжатую длл архиватором)> Ok. Всё теперь появится в проекте папка Resources. Следите чтобы у ресурсов стояла опция "Copy to Output Directory" в положении Do not copy.
4)В файлик App.cs или App.xaml.cs (у кого как) добавляем код
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public partial class App : Application
    {
        public App() : base()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }
        System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name.Contains("Dll_Reference_Name"))
            {
                return Assembly.Load(PROJECT_NAME.Properties.Resources.DLL_FILE_NAME);
            }
        }
    }
"Dll_Reference_Name" - точно такое же название, которое используете в using.
PROJECT_NAME - название вашего проекта, ваш namespace
DLL_FILE_NAME - название файла, который вы пихали в Resource

Более опытные могут хранить ресурсы в сжатом виде и распаковывать стрим перед извлечением, тогда размеры *.exe файла будут в 2-3 раза меньше.

Примечание: РЯДОМ С ФАЙЛОМ *.EXE БИБЛИОТЕКИ БЫТЬ НЕ ДОЛЖНО, ИНАЧЕ ЗАГРУЗКА С РЕСУРСОВ НЕ СРАБОТАЕТ!!!

Добавлено через 5 минут
В функции CurrentDomain_AssemblyResolve ещё в конце припишите return null; забыл скопипастить
13
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
01.06.2013, 15:40  [ТС] #10
сейчас попробую...

Добавлено через 15 минут
что то не понятно, куда вставлять код - у меня есть только статический класс Program, никакого app.cs...
при запуске пишет, что не удается загрузить сборку - файл не найден.
0
Dexiny
170 / 87 / 10
Регистрация: 27.05.2013
Сообщений: 290
01.06.2013, 15:41 #11
Вот сделал пример использования встроенных библиотек, а также использование бесплатной библиотеки 7Zip для сжатия ресурсов программы методом lzma, причём всё внутри exe файла. Для своего удобства программу писал на WPF.
0
Вложения
Тип файла: rar InternalZippedDLL.rar (401.8 Кб, 352 просмотров)
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
01.06.2013, 17:13  [ТС] #12
спасибо, у меня все почти так же, только не на wpf - до запуска приложения дело, похоже, не доходит - вываливается исключение "Невозможно загрузить сборку" или что-то типа этого и затем "заставка" - нет доступных исходных файлов...
0
уни
327 / 106 / 12
Регистрация: 06.03.2010
Сообщений: 234
16.08.2013, 03:09 #13
Вот тут есть пример стандартного способа загрузки dll из ресурсов через Assembly.Load(): Plugin.cs.

1. [BindingFlags.Instance] Метод Unzip() использует находящуюся в ресурсах библиотеку ICSharpCode.SharpZipLib.dll, которая распаковывает zip-архив, тоже находящийся в ресурсах.

Там же пример загрузки смешанной dll через Assembly.LoadFile():

2. [BindingFlags.Static] После распаковки в папке появляется другая dll (С++/CLI). Из неё тоже подгружается класс, но используются уже его статические методы и поля.

Смешанную dll (C++/CLI) нельзя загрузить прямо из ресурсов (при этому будет возникать исключение). Парни из Microsoft объяснили, что такая возможность поддерживаться не будет из-за проблем с безопасной инициализацией образа такой dll.
1
Miron50
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 1
18.02.2014, 19:45 #14
Маялся со схожей проблемой, есть несколько похожих проектов повторяющиеся методы вынесены наружу. Смержил их в один солюшен, но лень при рефакторинге в каждый ходить и менять код. Ответ подсказали программисты.
Итак:
1. библиотеку создаем отдельным проектом как обычный cs файл(НЕ как либу в этом же солюшене).
2. Подключаем её к нашему проекту Add->Existing Item-> здесь выбираем файл cs в котором нужный вам код(главное указать тип подключения "Add As Link") .
Все, и да будет Вам радость.
0
melhior4eg
0 / 0 / 0
Регистрация: 27.02.2014
Сообщений: 1
27.02.2014, 17:57 #15
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Код C#
public partial class App : Application
    {
        public App() : base()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }
        System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name.Contains("Dll_Reference_Name"))
            {
                return Assembly.Load(PROJECT_NAME.Properties.Resources.DLL_FILE_NAME);
            }
        }
    }
не работает способ в консольном приложении или что я не так делаю?

Добавлено через 2 часа 19 минут
Говорит что файл не найден... приложение не доходит до этого метода (не доходит до функции Main)

Добавлено через 1 час 48 минут
перекинул логику использующую подгружаемую библиотеку в отдельный файл класса и все заработало, проблема в том что это приложение должно было динамически компилироваться из другого приложения... поэтому все логика должна быть в одном файле... что делать?

Добавлено через 11 минут
Сам затупил, сам разобрался, логику использующую подгружаемую библиотеку просто не описывать в Main использовать отдельный класс и нет проблем

P.S.
Не пинайте сильно начинающего программиста, просто видимо надо было выговориться... почти день тупил над этим..
0
jml_murad
0 / 0 / 0
Регистрация: 05.08.2011
Сообщений: 11
10.11.2016, 10:54 #16
Цитата Сообщение от Conrad Посмотреть сообщение
Правой кнопкой по проекту Visual Studio, выбираешь Project Properties -> Resources -> Add Resource -> Add Existing File… И добавляешь следующий код в App.xaml.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
 
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");
 
    dllName = dllName.Replace(".", "_");
 
    if (dllName.EndsWith("_resources")) return null;
 
    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
 
    byte[] bytes = (byte[])rm.GetObject(dllName);
 
    return System.Reflection.Assembly.Load(bytes);
}
Как сделать для нескольких dll?
0
OwenGlendower
Супер-модератор
Эксперт .NET
8746 / 7750 / 3317
Регистрация: 17.03.2014
Сообщений: 15,247
Записей в блоге: 1
10.11.2016, 12:10 #17
Цитата Сообщение от jml_murad Посмотреть сообщение
Как сделать для нескольких dll?
Приведенный код уже умеет работать с несколькими dll. Главное чтобы она была включена в ресурсы под своим именем.
0
reverse28
0 / 0 / 3
Регистрация: 07.05.2012
Сообщений: 46
28.07.2017, 11:22 #18
Отличный способ, но есть одна проблема, что если одна(или несколько) библиотек используются в словаре ресурсов, который подключается в App.xaml через Application.Resources, таким образом получается что ссылка на эти библиотеки происходит раньше их подключения, возможно ли как-то решить эту проблему, оставив подключение словаря ресурсов для всего приложения?
0
28.07.2017, 11:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.07.2017, 11:22
Привет! Вот еще темы с решениями:

Объединить exe и dll
В проекте находится решение самой программы и решение dll ки. Как сделать чтобы...

Присоединение dll к exe
Подключал я библиотеки таким образом: Project>Add Reference>И добавлял нужную...

Внедрение dll в exe
Здравствуйте. Пишу программу для получения пакетов с сетевой карты....

Соединить .dll и .exe
Подключил библиотеку "Ionic.Zip" после построения проекта переместил .exe файл...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru