Как встроить спутниковую сборку в файл EXE

У меня проблема с тем, что мне нужно распространять проект C# в виде одного EXE-файла, который является не программой установки, а реальной программой. Также необходимо включить перевод, который в данный момент находится в подкаталоге.

Можно ли встраивать его прямо в двоичный файл?

4 ответа

Решение

Вот самое простое решение, которое я видел в интернете:

также удобная реализация этого решения: http://code.google.com/p/costura/wiki/HowItWorksEmbedTask

Краткий ответ - да, есть программа Assembly Linker (AL.exe), которая будет встраивать сборки таким образом. Его основным вариантом использования является локализация, звучит так, как будто это то, для чего она вам тоже нужна. Если это так, это должно быть просто.

Например:

al / t: lib /embed:strings.de.resources / culture: de /out:MyApp.resources.dll

или же

al.exe /culture:en-US /out:bin\Debug\en-US\HelloWorld.resources.dll /embed:Resources\MyResources.en-US.resources,HelloWorld.Resources.MyResources.en-US.resources / шаблон: Bin\Debug\HelloWorld.exe

Это пример прохождения MSDN с приведенными выше примерами и многим другим. Также вы можете прочитать этот блог, который объясняет его использование немного дальше.

Другой вариант - встроить другие сборки в EmbededResource. Затем обработайте домены приложения AssemblyResolve, отсюда вы можете прочитать сборку из ресурса и загрузить ее во время выполнения. Что-то вроде следующего:

public class HookResolver
{
    Dictionary<string, Assembly> _loaded;

    public HookResolver()
    {
        _loaded = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }

    System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        string name = args.Name.Split(',')[0];
        Assembly asm;
        lock (_loaded)
        {
            if (!_loaded.TryGetValue(name, out asm))
            {
                using (Stream io = this.GetType().Assembly.GetManifestResourceStream(name))
                {
                    byte[] bytes = new BinaryReader(io).ReadBytes((int)io.Length);
                    asm = Assembly.Load(bytes);
                    _loaded.Add(name, asm);
                }
            }
        }
        return asm;
    }
}

ILMerge создаст один exe-файл для вашего приложения. Вы можете скачать его с Microsoft. Он объединяет сборки и может их интернализовать, чтобы объединенные классы были установлены как внутренние. Это то, что я использовал для создания отдельных файловых выпусков несколько раз. Это довольно легко интегрировать в ваш процесс сборки.

Другие вопросы по тегам