Как объединить файлы в один исполняемый файл или уменьшить количество распространяемых файлов

У меня есть такие выходные файлы моего приложения WPF:

de\
es\
fr\
hu\
it\
pt-BR\
Resources\
ro\
ru\
sv\
zh-Hans\
FileHelpers.dll
FileHelpers.DataLink.dll
FileHelpers.ExcelStorage.dll
Interop.Excel.dll
Interop.Office.dll
Ionic.Zip.dll
wpftoolkit.dll
Xceed.Wpf.AvalonDock.dll
Xceed.Wpf.AvalonDock.Themes.Aero.dll
Xceed.Wpf.AvalonDock.Themes.Metro.dll
Xceed.Wpf.AvalonDock.Themes.VS2010.dll
Xceed.Wpf.DataGrid.dll
Xceed.Wpf.Toolkit.dll
MyApp.Common.Extensions.dll
MyApp.Common.Helpers.dll
MyApp.Common.Types.Attributes.dll
MyApp.Security.dll
MyApp.Wpf.Controls.dll
MyApp.exe
MyApp.exe.config
licence.key
error.log

Все, что началось с MyApp, разработал я сам, все остальное сделал 3dParty. Я хочу распространить свое приложение, но для этого я хочу объединить все, что возможно, для распространения минимального количества файлов.

Я пытался использовать ilmerge для объединения моих файлов в один, но получал ошибку:

ILMerge.Merge: ERROR!!: Duplicate type 'XamlGeneratedNamespace.GeneratedInternal TypeHelper' found in assembly 'Xceed.Wpf.DataGrid'. Ответ на этот вопрос я нашел здесь Причина ошибки xeed Чем я читая ограничения ilmerge и сборка как ресурсы Джеффри Рихтера

Итак, я обнаружил, что решение Джеффри Рихтера весьма полезно. Но я не могу применить это для своей программы, потому что в сборках нет атрибута Build Action.

Могу ли я что-нибудь сделать для достижения своей цели?

введите описание изображения здесь


person sreginogemoh    schedule 01.11.2013    source источник
comment
Просто из любопытства, почему вы хотите минимизировать количество файлов? Это просто не похоже на очень продуктивное использование вашего времени ...   -  person Mike Dinescu    schedule 02.11.2013
comment
@Miky Dinescu he he he, возможно, вы правы, но я хочу понять, почему идея Джеффри мне не подходит.   -  person sreginogemoh    schedule 02.11.2013


Ответы (2)


Взгляните на SmartAssembly RedGate.

person gap    schedule 01.11.2013
comment
Хех, я попробую, но мне все еще интересно, почему подход Джеффри не работает в моем случае ... - person sreginogemoh; 02.11.2013

Чтобы идея Джеффри работала, вы должны добавлять свои сборки не только в качестве ссылок. Просто добавьте библиотеки DLL в качестве существующего элемента (щелкните правой кнопкой мыши проект-> Добавить-> Существующий элемент) в свой проект, и вы получите для них свойство Действие сборки. Также установите для свойства Копировать локальное значение false для ссылок, которые вы добавляете в качестве встроенного ресурса.

введите описание изображения здесь

Конструктор класса приложения:

public partial class App : Application
{
    public App()
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }
    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var dllName = new AssemblyName(args.Name).Name + ".dll";
        var execAsm = Assembly.GetExecutingAssembly();
        var resourceName = execAsm.GetManifestResourceNames().FirstOrDefault(s => s.EndsWith(dllName));
        if (resourceName == null) return null;
        using (var stream = execAsm.GetManifestResourceStream(resourceName))
        {
            var assbebmlyBytes = new byte[stream.Length];
            stream.Read(assbebmlyBytes, 0, assbebmlyBytes.Length);
            return Assembly.Load(assbebmlyBytes);
        }

    }
}

Обратите внимание, что этот метод потребляет больше памяти, чем обычная загрузка dll.

person Deffiss    schedule 01.11.2013
comment
Отлично, а также будет использовать RedGate's SmartAssembly, как предложил @gap - person sreginogemoh; 02.11.2013
comment
Как это повлияет на список сборок, на которые имеются ссылки, в папке ссылок? Влияет ли это на время компиляции или время выполнения? Я очень хочу это проверить, понятия не имею, как все это работает? - person IbrarMumtaz; 30.11.2013
comment
У вас должны быть ссылки на все сборки, как в обычной ситуации, чтобы предоставить компилятору всю необходимую информацию о типах. Вы устанавливаете Copy local в false, потому что все сборки (которых нет в GAC) вы загружаете из ресурсов во время выполнения. Это происходит, когда среда CLR впервые встречает типы из этой библиотеки DLL и вызывает JIT-компиляцию. Из-за этого вы не можете использовать такие типы непосредственно в Main (). - person Deffiss; 01.12.2013