将 DLL 作为嵌入资源包含在 WPF 项目中

发布于 2024-11-17 00:50:06 字数 1490 浏览 1 评论 0 原文

我正在关注 http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx< /a>

我已将 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

代码在遇到stream.Length 时抛出异常,因为它为空。

我无法使用 ILMerge,因为它是一个 WPF 项目。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

歌入人心 2024-11-24 00:50:06

您必须将字符串“AssemblyLoadingAndReflection”更改为应用程序程序集的名称。

您可以通过使用更多反射来使此代码更加通用,可以做一件事:

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

不要忘记附加一个点。如果 dll 不在应用程序程序集的资源中,这当然不起作用。

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.

荭秂 2024-11-24 00:50:06

HB的回答其实并不完全正确。我们需要的前缀不是程序集的名称,而是项目的默认命名空间。这可能不可能完全可靠,但下面的代码比假设它与程序集名称相同要可靠得多。

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

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);
女中豪杰 2024-11-24 00:50:06

内森菲利普的答案对我来说就像一个魅力..

这就是对我有用的整个方法
(它也适用于多个 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);

            }

        };
    }

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

            }

        };
    }
魔法少女 2024-11-24 00:50:06

我尝试了上述所有答案,但它们对我不起作用。我发现了这篇文章,它很有魅力。

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

我发现.csproj 文件还需要编辑。这篇文章解释了如何做所有事情。

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.

嗼ふ静 2024-11-24 00:50:06

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文