Слить .dll в сборку C #? - PullRequest
       31

Слить .dll в сборку C #?

4 голосов
/ 05 декабря 2010

Использование # C.net 3.5

Мне известны ILMerge и аналогичные приемы, но я бы хотел использовать предложения Джеффри Рихтера .

После добавления этого кода в конструктор возникают проблемы с пространством имен.

Код Джеффри Рихтера:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
    String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(args.Name).Name + ".dll";
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) {
        Byte[] assemblyData = new Byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);
    }
};

Я установил две библиотеки DLL как «Встроенный ресурс» и добавил их в качестве ссылки, нокогда я собираю программу, две dll по-прежнему "Un-embbeded", я затем удалил их в качестве ссылки, но затем, когда я собираю программу, появляются ошибки, говорящие: "тип или пространство имен не может быть найдено ... вы пропалидиректива использования или ссылка на сборку? "У меня есть два пространства имен, добавленных в качестве директивы using ..., затем я попытался удалить две ссылки и две директивы using и все еще ошибки.

вот мой код:

using System.Reflection;
    namespace WindowsFormsApplication2
    {
        public partial class Ndice : Form
        {
            public Ndice()
            {
                AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
                {
                    String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(args.Name).Name + ".dll";
                    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                    {
                        Byte[] assemblyData = new Byte[stream.Length];
                        stream.Read(assemblyData, 0, assemblyData.Length);
                        return Assembly.Load(assemblyData);
                    }
                };
                InitializeComponent();
               }
           }
        }

Ответы [ 3 ]

3 голосов
/ 08 декабря 2010

Из описания в вашем вопросе некоторые вещи не ясны, которые могут понадобиться для ответа:

  1. Что именно не работает?У вас происходит сбой во время компиляции или во время выполнения?
  2. Можете ли вы показать код, который не компилируется или не работает во время выполнения?
  3. Что вы имеете в виду, когда говорите сборки«не встроены»?

По сути, насколько я понимаю, у вас есть код, который пытается использовать классы из двух сборок.Этот код static , что означает, что классы должны быть известны во время время компиляции .Или, другими словами, у вас должна быть ссылка на эти 2 сборки, чтобы скомпилировать код, использующий типы, определенные в них.

Я не совсем понимаю, что пошло не так, когда вы добавили эти сборки какссылка.Если вас беспокоит то, что вы видели, как они копируются в каталог bin / debug , это не должно было помешать их встраиванию в основную сборку.Поэтому для тестирования вы можете попробовать вручную удалить их из bin / debug или, возможно, установить для них значение «copy local = false».

Еще одна вещь - ошибка, с которой вы столкнулись, которая упоминала «использование "и" пространств имен "на самом деле не касалось пространств имен.Эта ошибка означает, что компилятор не нашел нужные ему типы.Возможно, это связано с тем, что вы удалили ссылки на 2 сборки.

3 голосов
/ 05 декабря 2010

Поместите его в конструктор, а не InitializeComponent (). Добавление с использованием директив в файл исходного кода основного класса не является проблемой.

0 голосов
/ 17 сентября 2013
String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(args.Name).Name + ".dll";

следует изменить на:

String resourceName = Application.Current.GetType().Namespace + "." + new AssemblyName(args.Name).Name + ".dll";
...