Есть солюшен (Solution). В нем 4 проекта. Один главный, три второстепенных. Главны
проект использует типы из второстепенных и наоборот. Короче все они переплетены. Как все это скомпилировать в один .EXE файл для последующего распространения?
UPD
Т.к. похоже,что не все поняли о чем речь, то постараюсь дополнить свой вопрос.
Вот небольшой пример:
В solution Explorer видно, что в Solution добавлено два проект. Проект App2 зависит от проекта App1. App1 добавлен в References.
Так же прописаны соответствующие зависимости.
Если просто откомпилировать этот Solution, то на выходе получим два файла - App2.ex
и App1.dll. Таким образом, чтобы приложение заработало, скажем на другом компьютере
нужно переписать туда два этих файла. Иначе произойдет ошибка времени выполнения. Что-т
вроде Could not load file or assembly. The system cannot find the file specified. Так вот хотелось бы откомпилировать приложение таким образом, чтобы в итоге получился только один файл - App2.exe. И чтобы распространять это приложение можно было одним файлом. А файл App1.dll была как бы встроена в него.
Ответы
Ответ 1
Возможные решения:
Слияние сборок в одну после компиляции
Несколько сборок можно склеить в одну уже после компиляции, используя утилиту ILMerge.
Она есть на NuGet.org:
Install-Package ilmerge
Формат вызова:
ilmerge
/lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"
/lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"
/targetplatform:v4
/out:out.dll mydll1.dll mydll2.dll
перед использованием пути стоит подправить на актуальные.
Аналогичные утилиты - il-repack, Mono.Merge
Включение DLL в EXE в виде Embedded Resource с подменой стандартного механизма загрузки:
Добавить bin\someassembly.dll в проект exe через Add Existing Item / стрелка на Add / Add as Link, выставить Build Type = Embedded Resource
Добавить проект someassembly в References. Выставить у референса Copy Local = false - чтобы избежать копирования в bin.
Обработать CurrentDomain_AssemblyResolve:
using System;
using System.Reflection;
using System.Windows.Forms;
namespace WindowsFormsApplication7
{
static class Program
{
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name).Name;
if (assemblyName == "someassembly")
{
using (var stream = typeof(Program).Assembly.GetManifestResourceStream(
"WindowsFormsApplication7." + assemblyName + ".dll"))
{
byte[] assemblyData = new byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
else
{
return null;
}
}
}
}
Это минимальный рабочий пример. Если не работает - запускайте под отладчиком. Скоре
всего вы не угадали с именем ресурса, и GetManifestResourceStream возвращает null. Убедитесь, что тип у айтема выставлен именно в Embedded Resource (а не просто в Resource). Просмотреть имена всех доступных ресурсов можно прямо в отладчике, вызовом
typeof(Program).Assembly.GetManifestResourceNames()
Проект целиком на гитхабе, на примере SevenZipSharp: https://github.com/PashaPash/SevenZipSharp-Embedded
Включение сборок в виде ресурсов, автоматический вариант
Устанавливаете пакет Costura.Fody через nuget и получаете один exe на выходе.
> PM> Install-Package Costura.Fody
Альтернативы:
Решение от Vlad - компиляция в netmodule с последющим слиянием
Сборка через добавление всех исходников в еще один большой проект - от @Qwertiy
Ответ 2
Поправлю сам себя, решить проблему Вам поможет маленькая утилита от Microsoft - ILMerge. Добавлю, что есть хорошая статья на данную тему
Ответ 3
Есть ещё и костыльный способ: создать новый проект и в него добавить как существующие все файлы с кодом, после чего скомпилировать.
Комментариев нет:
Отправить комментарий