【问题标题】:Using an embedded DLL?使用嵌入式 DLL?
【发布时间】:2010-12-24 07:41:55
【问题描述】:

是否有关于如何在 c# 源代码中使用资源嵌入 dll 的详细指南?我在 Google 上找到的所有指南似乎都没有多大帮助。这都是“创建一个新课程”或“ILMerge”这个和“.NETZ”那个。但是我不确定如何使用 ILMerge 和 .NETZ 的东西,并且关于类的指南省略了制作类文件后要做什么,因为这样做后我没有发现任何新东西。例如,this。添加类和函数后,我不知道如何从我的资源中获取 dll。

所以,具体来说,我正在寻找的是关于如何使用 .dll 文件的指南,该文件是 embedded into Resources 以便能够调用 class,而没有遗漏部分。请记住,我对 C# 编码不是很有经验。提前致谢。 :D

附言。尽量不要使用那些大词。我很容易迷路。

【问题讨论】:

  • 你为什么想要这种行为?如果您只想发送一个文件,请使用安装程序。如果您不希望人们查看您的程序集,这也是一个糟糕的解决方案。
  • 你也可以在 codeplex 试试这个ilmergertoo

标签: c# dll resources embedded-resource


【解决方案1】:

您可以使用Assembly.GetManifestResourceStreamStream 获取到DLL,但要对其进行任何操作,您需要将其加载到内存中并调用Assembly.Load,或者将其解压缩到文件系统(然后很有可能仍然调用Assembly.LoadAssembly.LoadFile,除非你实际上已经依赖它)。

加载程序集后,您必须使用反射来创建类实例或调用方法等。所有这些都非常繁琐——尤其是我永远记不起调用@987654330 的各种重载的情况@(或类似方法)。 Jeff Richter 的"CLR via C#" 书将是您​​办公桌上的有用资源。

您能否提供更多信息,说明您为什么需要这样做?我已经将清单资源用于各种事情,但从不包含代码......你有什么理由不能将它与你的可执行文件一起发布?

这是一个完整的例子,虽然没有错误检查:

// DemoLib.cs - we'll build this into a DLL and embed it
using System;

namespace DemoLib
{   
    public class Demo
    {
        private readonly string name;

        public Demo(string name)
        {
            this.name = name;
        }

        public void SayHello()
        {
            Console.WriteLine("Hello, my name is {0}", name);
        }
    }
}

// DemoExe.cs - we'll build this as the executable
using System;
using System.Reflection;
using System.IO;

public class DemoExe
{
    static void Main()
    {
        byte[] data;
        using (Stream stream = typeof(DemoExe).Assembly
               .GetManifestResourceStream("DemoLib.dll"))
        {
            data = ReadFully(stream);
        }

        // Load the assembly
        Assembly asm = Assembly.Load(data);

        // Find the type within the assembly
        Type type = asm.GetType("DemoLib.Demo");

        // Find and invoke the relevant constructor
        ConstructorInfo ctor = type.GetConstructor(new Type[]{typeof(string)});
        object instance = ctor.Invoke(new object[] { "Jon" });

        // Find and invoke the relevant method
        MethodInfo method = type.GetMethod("SayHello");
        method.Invoke(instance, null);
    }

    static byte[] ReadFully(Stream stream)
    {
        byte[] buffer = new byte[8192];
        using (MemoryStream ms = new MemoryStream())
        {
            int bytesRead;
            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, bytesRead);
            }
            return ms.ToArray();
        }
    }
}

构建代码:

> csc /target:library DemoLib.cs
> csc DemoExe.cs /resource:DemoLib.dll

【讨论】:

  • 嗯,除了“我为什么想要这个”部分,我什么都不明白。我想包含一个 dll 文件来调用一个函数,但不希望将 dll 复制到机器上。基本上是一个多合一的包。
  • @Kevin:如果您对此一无所知,那么您可能需要进行更多的 .NET 编码才能真正做好准备。即使您可以根据我的示例获得一些代码,您也可能会发现很难维护。您到底有多想避免复制 DLL?
  • 那么我建议要么阅读 ILMerge 的文档,要么通过 C# 购买 CLR :)
  • 我认为我们大多数人希望这样做的原因是,至少在我的情况下,是构建一个用于许可保护的单个 *.dll,可以嵌入到多个 *.dll 添加-我们开发的各种产品的ins。我现在正在重新研究这个,因为我正在尝试公开我编写的插件,并且我做了很多相同的开发,所以将单个 *.dll 嵌入到各种插件中是很重要的更好的代码重用与将 *.cs 文件复制到我们的每个项目中......从“代码隐藏”的角度来看,它也使它变得更有趣。让人不得不多想:)
【解决方案2】:

您可能需要使用 ILMerge。看起来它会自然地为你解决问题。

http://research.microsoft.com/en-us/people/mbarnett/ILMerge.aspx

【讨论】:

  • 好吧,问题是,我不知道如何使用它。有导游吗?
  • 工具中有安装说明。
  • 在您的代码中引用目标程序集,然后照常调用您的函数。稍后您可以使用 ilmerge 将这两个程序集合并为一个。您可以按如下方式使用该工具: ilmerge /t:library /closed /internalized /out:newdll.dll lib1.dll lib2.dll 您可以阅读命令行帮助中的进一步说明或 Jon 指出的附加说明。
  • 在“如何使用 ilmerge”的几个谷歌搜索之后,ILMerge 似乎只是将 dll 合并在一起,这样你就剩下 1 个可以调用所有函数的 dll 了吗?如果是这样,我正在尝试这样做,以便我可以将 exe 和 dll 合并在一起,同时还能够调用 dll 中的函数。
  • 我相信 ILMerge 没有这样的限制。如果您的最终产品是一个 EXE 文件,那么您将使用“ilmerge /t:exe ...”而不是上述语法。你为什么不试试看它是否有效?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多