如何使用从嵌入资源中加载的 DLL?

11

我有一个 DLL >> System.Data.SQLite.dll

要以正常的方式使用它 > 只需将其添加为引用即可

using System.Data.SQLite;

接下来,我可以使用此DLL中的所有函数。

但是,我想将我的app.exe和这个DLL合并成一个单独的文件。 我尝试过使用ILmerge,但失败了。据我所知,ILmerge无法合并非托管的DLL。

因此,我尝试了另一种方法>将DLL作为嵌入式资源。 使用以下代码,我可以将其作为程序集加载:

Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyApp.System.Data.SQLite.dll");
byte[] ba = null;
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
    int read;
    while ((read = stm.Read(buffer, 0, buffer.Length)) > 0)  
    {
        ms.Write(buffer, 0, read);
    }
    ba = ms.ToArray();
}
Assembly sSQLiteDLL = Assembly.Load(ba);

但是,我该如何使用SQLiteDLL中的函数呢?

我也尝试在属性中将DLL添加为资源,然后像这样进行加载:

public Form1()
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    InitializeComponent();
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    AppDomain domain = (AppDomain)sender;
    if (args.Name.Contains("System_Data_SQLite"))
    {
        return domain.Load(MyApp.Properties.Resources.System_Data_SQLite);
    }
    return null;
}

上面解释了我目前所拥有的,但我不知道接下来该怎么做才能使用 DLL?我仍然无法使用 DLL 内部的函数。

例如,当我输入以下内容时:

SQLiteCommand cmd = new SQLiteCommand();

Visual Studio 提示:

错误 21:找不到类型或命名空间名称 'SQLiteCommand'(是否缺少 using 指令或程序集引用?)

你能分享一下你的想法吗?谢谢。


2
你应该能够结合上述方法来实现这一点。但是,这确实需要将SQLite程序集添加为引用,否则VS无法知道如何处理它。不过,我不确定这如何解决您的本地DLL问题。在运行时,您仍然需要将其作为物理文件。 - M.Babcock
你问了一个非常类似的问题,并得到了许多答案,其中包括一些链接等。- 你查看了这些答案/链接吗? - Yahia
@Yahia:正在学习中,需要一些时间。我尝试了SmartAssembly,它成功了。但是无法使用ILmerge,可能漏掉了一些参数。对于ILmerge,我使用的参数是:'ilmerge /out:MyApp2.exe MyApp.exe System.Data.SQLite.dll' 出现了一个错误,它说程序集System.Data.SQLite.dll没有标记为仅包含托管代码。现在我将尝试手动合并代码中的DLL。如果成功,我会告诉你的。嘿,谢谢你的帮助。非常感激。 - alont
2个回答

7
你可以同时嵌入程序集和引用它(在VS中)... 但是,根据你想要使用它的方式,你需要引用它!你不引用程序集的原因是什么?从嵌入的程序集(托管)中使用类型而不引用它有点困难,但可以使用反射等方法实现。请参阅以下链接(它们包括参考材料和一些示例代码等):

对于嵌入式托管 DLL,您有几个选项:

或者

  • 使用类似SmartAssembly(商业)的工具
    它可以嵌入和合并等操作(无需更改您的源代码)

或者

  • 在不到10行代码中编写自己的代码(免费但只需最少的源代码更改)
    将所有必要的依赖项标记为“嵌入式资源” - 这样它们就会包含在EXE文件中...您需要设置一个{{link2:AssemblyResolve}}处理程序,在运行时从资源中读取并返回所需的DLL给.NET运行时...

5
嗨,Yahia,经过一些项目的成功后,我决定写一个教程。阅读更多:[链接](http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource) - alont
“code that yourself”链接对我来说是失效的(404)。” - Thomas Weller

-1

这不是使用AppDomain中加载的程序集的方法。请阅读本文:如何将程序集加载到应用程序域中

简而言之,您应该使用方法名称(例如SqlCommand)调用GetMethod(),然后通过.Invoke()方法调用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接