Включение DLL в качестве встроенного ресурса в проект WPF - PullRequest
4 голосов
/ 23 июня 2011

Я подписан на http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx

Я добавил WPFToolkit.Extended.dll в свое решение и установил для его Действия по компоновке встроенный ресурс.

В App.OnStartup (StartupEventArgs e) у меня есть следующий код:

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

Отладчик дважды выполняет этот блок кода.

Первый раз:

resourceName is "AssemblyLoadingAndReflection.StatusUtil.resources.dll"
assemblyName is "StatusUtil, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
stream is null

Второй раз:

resourceName is "AssemblyLoadingAndReflection.WPFToolkit.Extended.resources.dll"
assemblyName is "StatusUtil, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
stream is null

Код генерирует исключение при попадании в поток. Длина, поскольку он равен нулю.

Я не могу использовать ILMerge, потому что это проект WPF.

Ответы [ 5 ]

7 голосов
/ 23 июня 2011

Вы должны изменить строку "AssemblyLoadingAndReflection" на имя сборки вашего приложения.

Одна вещь, которую вы можете сделать, чтобы сделать этот код более универсальным, используя некоторые дополнительные отражения:

Assembly.GetExecutingAssembly().FullName.Split(',').First()

Не забудьте добавить точку.Это, конечно, не будет работать, если dll не находится в ресурсах сборки приложения.

2 голосов
/ 06 апреля 2015

Ответ Натана Филипа сработал для меня как оберег ..

Это весь метод, который сработал для меня (и он работает для нескольких DLL)

public MainWindow()
    {
        InitializeComponent();

        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            Assembly thisAssembly = Assembly.GetEntryAssembly();
            String resourceName = string.Format("{0}.{1}.dll",
                thisAssembly.EntryPoint.DeclaringType.Namespace,
                new AssemblyName(args.Name).Name);

            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            {

                Byte[] assemblyData = new Byte[stream.Length];

                stream.Read(assemblyData, 0, assemblyData.Length);

                return Assembly.Load(assemblyData);

            }

        };
    }
2 голосов
/ 18 июля 2012

Ответ HB на самом деле не совсем правильный.Префикс, который нам нужен, это не имя сборки, а пространство имен проекта по умолчанию.Это, вероятно, невозможно получить полностью надежно, но следующий код будет гораздо надежнее, если предположить, что он совпадает с именем сборки.

Assembly thisAssembly = Assembly.GetEntryAssembly();
String resourceName = string.Format("{0}.{1}.dll",
    thisAssembly.EntryPoint.DeclaringType.Namespace,
    new AssemblyName(args.Name).Name);
0 голосов
/ 14 июля 2016

У меня есть полное объяснение того, как динамически загружать встроенные сборки в вопросе StackOverflow Встроенная DLL VB.NET в другую DLL в качестве встроенного ресурса?

0 голосов
/ 29 июня 2016

Я попробовал все вышеперечисленные ответы, и они не работали для меня.Я нашел этот пост, и он работал как шарм.

Пост: http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application

Я обнаружил, что файл .csproj также нужно редактироватьВ посте объясняется, как все сделать.

...