Including a DLL as an Embedded Resource in a WPF p

2019-03-31 03:45发布

I'm following http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx

I've added WPFToolkit.Extended.dll to my solution, and set its Build Action to Embedded Resource.

In App.OnStartup(StartupEventArgs e) I have the following code:

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);
    }
};

The debugger hits this block of code twice.

First time:

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

Second time:

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

The code throws an exception when it hits stream.Length, since it's null.

I can't use ILMerge because it's a WPF project.

5条回答
时光不老,我们不散
2楼-- · 2019-03-31 04:13

I tried all of the above answers and they did not work for me. I found this post and it worked like a charm.

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

I found that the .csproj file also needs to be edited. The post explains how to do everything.

查看更多
仙女界的扛把子
3楼-- · 2019-03-31 04:18

Nathan Philip's Answer worked like a charm for me..

This is the entire method that worked for me (and it works for multiple dlls also)

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);

            }

        };
    }
查看更多
该账号已被封号
4楼-- · 2019-03-31 04:21

I have a full explanation of how to dynamically load embedded assemblies in StackOverflow question VB.NET embedded DLL in another DLL as embedded resource?

查看更多
ら.Afraid
5楼-- · 2019-03-31 04:34

The answer by H.B. is actually not quite right. The prefix we need is not the name of the assembly, but the default namespace of the project. This is probably impossible to get entirely reliably, but the following code would be much more reliable than assuming it's the same as the assembly name.

Assembly thisAssembly = Assembly.GetEntryAssembly();
String resourceName = string.Format("{0}.{1}.dll",
    thisAssembly.EntryPoint.DeclaringType.Namespace,
    new AssemblyName(args.Name).Name);
查看更多
女痞
6楼-- · 2019-03-31 04:36

You have to change the string "AssemblyLoadingAndReflection" to the name of your application assembly.

One thing you can do to make this code more generic by using some more reflection:

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

Don't forget to append a dot. This will of course not work if the dll is not in the resources of the application assembly.

查看更多
登录 后发表回答