C#使用SqlCipher以及使用Costura.Fody合并DLL进EXE

本文介绍了如何在C# Windows桌面应用中使用SqlCipher加密SQLite数据库,以及通过Costura.Fody将DLL合并到EXE文件中。在.NET Framework 4.6.2环境下,详细阐述了设置项目属性以支持长路径,安装并配置SqlCipher和Costura.Fody的过程,并解决了因首选32位导致的问题。同时,指出了在使用Costura.Fody时需要注意排除特定DLL以避免运行时错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建C# Windows 桌面 窗体应用

在这里插入图片描述
框架.NET Framework 4.6.2
在这里插入图片描述

使程序支持长路径

4.6.2以后才System.IO模块才开始支持长路径
参看:
https://www.cnblogs.com/zerodai/p/10224946.html#idx_13
https://devblogs.microsoft.com/dotnet/announcing-net-framework-4-6-2/

默认项目属性的BUG

项目属性->生成->下面这个勾(首选32位)一定要去掉 一定要去掉 一定要去掉 这是个VS默认设置的BUG 不去掉这个 简单的获取文件大小就会出现问题
在这里插入图片描述
在勾选上首选32位后,测试如下代码:

        private void button1_Click(object sender, EventArgs e)
        {
            System.IO.FileInfo fi = new System.IO.FileInfo(@"c:\windows\regedit.exe");
            MessageBox.Show(Convert.ToString(fi.Length));
        }

在这里插入图片描述
实际大小为 357888:
在这里插入图片描述
去除首选32位后就正常了
在这里插入图片描述

使用NuGet

在这里插入图片描述

SqlCipher的使用

用途:加密SQLite数据库

加载方法:
搜索SqlCipher 发现有3个相关

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
区别暂不清楚,目前使用作者为官方SQLite-net
URL:https://github.com/praeclarum/sqlite-net
加载后会自动引入一大堆相关的DLL
在这里插入图片描述
SQLitePCLRaw.lib.e_sqlcipher.2.0.3
System.Buffers.4.4.0
System.Numerics.Vectors.4.4.0
System.Runtime.CompilerServices.Unsafe.4.5.2
System.Memory.4.5.3
SQLitePCLRaw.core.2.0.3
SQLitePCLRaw.provider.dynamic_cdecl.2.0.3
SQLitePCLRaw.bundle_e_sqlcipher.2.0.3
sqlite-net-sqlcipher.1.7.335

引入前:
在这里插入图片描述
引入后:
在这里插入图片描述
编译后除一堆DLL外,还有一个runtimes目录
在这里插入图片描述
使用方法:

		using SQLite;
		
        [Table("stock")]
        public class Stock
        {
            [PrimaryKey, AutoIncrement]
            [Column("id")]
            public int Id { get; set; }

            [Column("symbol")]
            public string Symbol { get; set; }
        }


        [Table("valuation")]
        public class Valuation
        {
            [PrimaryKey, AutoIncrement]
            [Column("id")]
            public int Id { get; set; }

            [Indexed]
            [Column("stock_id")]
            public int StockId { get; set; }

            [Column("time")]
            public DateTime Time { get; set; }

            [Column("price")]
            public decimal Price { get; set; }
        }
        
            var options = new SQLiteConnectionString(@"d:\test1.db", true, key: "password");
            SQLiteAsyncConnection encryptedDb = new SQLiteAsyncConnection(options);

            encryptedDb.CreateTableAsync<Stock>();
            encryptedDb.CreateTableAsync<Valuation>();

Costura.Fody的使用(合并SqlCipher的一大堆DLL)

用途:合并DLL文件进EXE,减少目录下一堆三方DLL

加载方法:
搜索Costura.Fody
在这里插入图片描述
URL:https://github.com/Fody/Costura

会增加如下DLL:
在这里插入图片描述
Fody.6.3.0
Microsoft.NETCore.Platforms.1.1.0
Microsoft.Win32.Primitives.4.3.0
System.AppContext.4.3.0
System.Collections.4.3.0
System.Collections.Concurrent.4.3.0
System.Console.4.3.0
System.Diagnostics.Debug.4.3.0
System.Diagnostics.DiagnosticSource.4.3.0
System.Diagnostics.Tools.4.3.0
System.Diagnostics.Tracing.4.3.0
System.Globalization.4.3.0
System.Globalization.Calendars.4.3.0
System.IO.4.3.0
System.IO.Compression.4.3.0
System.IO.Compression.ZipFile.4.3.0
System.IO.FileSystem.Primitives.4.3.0
System.IO.FileSystem.4.3.0
System.Linq.4.3.0
System.Linq.Expressions.4.3.0
System.Net.Primitives.4.3.0
System.Net.Sockets.4.3.0
System.ObjectModel.4.3.0
System.Reflection.4.3.0
System.Reflection.Extensions.4.3.0
System.Reflection.Primitives.4.3.0
System.Resources.ResourceManager.4.3.0
System.Runtime.4.3.0
System.Runtime.Extensions.4.3.0
System.Runtime.Handles.4.3.0
System.Runtime.InteropServices.4.3.0
System.Runtime.InteropServices.RuntimeInformation.4.3.0
System.Runtime.Numerics.4.3.0
System.Security.Cryptography.Encoding.4.3.0
System.Security.Cryptography.Primitives.4.3.0
System.Security.Cryptography.Algorithms.4.3.0
System.Security.Cryptography.X509Certificates.4.3.0
System.Net.Http.4.3.0
System.Text.Encoding.4.3.0
System.Text.Encoding.Extensions.4.3.0
System.Text.RegularExpressions.4.3.0
System.Threading.4.3.0
System.Threading.Tasks.4.3.0
System.Threading.Timer.4.3.0
System.Xml.ReaderWriter.4.3.0
System.Xml.XDocument.4.3.0
NETStandard.Library.1.6.1
Costura.Fody.5.0.2

使用参看:https://www.itsvse.com/thread-4677-1-1.html
直接编译后,所有的DLL文件直接合并入EXE文件,不需要任何代码

修改:FodyWeavers.xml
默认生成的:

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <Costura />
</Weavers>

CreateTemporaryAssemblies 可有可无
注意SqlCipher的SQLitePCLRaw.core不能打包进exe,需要加入到ExcludeAssemblies参数中
DisableCleanup参数用于清理用不到的dll

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <Costura CreateTemporaryAssemblies="true" ExcludeAssemblies="SQLitePCLRaw.core" DisableCleanup="false" />
</Weavers>

不修改的后果:
1、SqlCipher使用Async不会出错引发中断,但没有效果
2、SqlCipher若不使用Async

            var options = new SQLiteConnectionString(@"d:\test1.db", true, key: "password");
            SQLiteConnection encryptedDb = new SQLiteConnection(options);

            encryptedDb.CreateTable<Stock>();
            encryptedDb.CreateTable<Valuation>();

在new SQLiteConnection的时候会引发路径形式不合法的错误,错误如下:
在这里插入图片描述

System.TypeInitializationException
HResult=0x80131534
Message=“SQLite.SQLiteConnection”的类型初始值设定项引发异常。
Source=SQLite-net
StackTrace:
at SQLite.SQLiteConnection…ctor(SQLiteConnectionString connectionString)
at WindowsFormsApp3.Form1.button1_Click(Object sender, EventArgs e) in C:\Users\YY\source\repos\WindowsFormsApp3\WindowsFormsApp3\Form1.cs:line 56
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at WindowsFormsApp3.Program.Main() in C:\Users\YY\source\repos\WindowsFormsApp3\WindowsFormsApp3\Program.cs:line 19

此异常最初是在此调用堆栈中引发的:
[外部代码]

内部异常 1:
ArgumentException: 路径的形式不合法。

<think>好的,我现在需要回答用户关于如何在C#项目中使用Costura.Fody指定打包特定的DLL文件的问题。首先,我得回忆一下Costura.Fody的基本工作原理。根据引用[1],Costura.Fody会在构建时将所有被引用的DLL嵌入到EXE文件中,当程序运行时找不到某个DLL时会触发AssemblyResolve事件,然后从嵌入的资源中提取。不过用户的需求是只嵌入特定的DLL,而不是全部。 接下来,我需要查看用户提供的引用内容。引用[2]提到了在FodyWeavers.xml文件中配置Unmanaged32Assemblies和Unmanaged64Assemblies节点,指定SQLite.Interop。这可能是一个排除或包含特定DLL的例子。但用户的问题是关于“仅嵌入指定的DLL”,也就是只打包他们选择的那些,而不是全部。 通常,Costura.Fody默认嵌入所有引用的DLL,所以如果要仅嵌入特定DLL,可能需要排除其他不需要的。根据官方文档或已知配置,Costura.Fody提供了IncludeAssemblies和ExcludeAssemblies的配置选项。例如,使用IncludeAssemblies来指定需要包含的DLL,或者用ExcludeAssemblies来排除不需要的。不过用户提供的引用中没有直接提到这些配置,可能需要结合已有的资料和用户提供的例子来推断。 引用[3]提到安装特定版本的Costura.Fody,但并没有直接说明如何配置包含特定的DLL。因此,我需要确定正确的配置语法。根据引用[2]中的示例,FodyWeavers.xml的结构是包含Costura节点,里面可以有不同的子节点。例如,要排除某些DLL,可以使用ExcludeAssemblies,并在其中用正则表达式匹配不需要的DLL名称。反之,如果要包含特定的DLL,可能需要使用IncludeAssemblies节点,并列出需要包含的DLL名称。 假设用户想仅包含指定的DLL,比如A.dll和B.dll,那么配置应该是这样的:在FodyWeavers.xml中,设置IncludeAssemblies节点,并使用正则表达式来匹配这些DLL的名称。同时,可能需要排除其他所有DLL,但这可能需要更复杂的正则表达式,或者结合使用Include和Exclude的组合。 例如,配置可能如下: <Costura> <IncludeAssemblies> A B </IncludeAssemblies> </Costura> 这样,只有A.dll和B.dll会被包含,其他则不会被嵌入。但需要确认IncludeAssemblies是否支持多个条目,以及是否需要使用正则表达式。例如,可能需要写成A|B来匹配这两个名称。 另外,用户提供的引用[2]中的例子是处理非托管的DLL,如SQLite.Interop,这可能属于特殊情况,需要单独配置。但这里用户的问题可能更一般,是关于托管DLL的嵌入。 总结步骤应该是: 1. 安装Costura.Fody包。 2. 创建或修改FodyWeavers.xml。 3.Costura节点下配置IncludeAssemblies,指定需要包含的DLL名称(不带扩展名)。 4. 确保其他DLL不被包含,可能需要设置ExcludeAssemblies为.*,但需要测试或查阅文档。 需要注意可能的语法问题,比如是否需要正则表达式,以及是否区分大小写等。例如,IncludeAssemblies中的条目是否需要用竖线分隔,或者作为多个子元素。根据引用[2]的例子,Unmanaged32Assemblies中的内容是换行分隔的,所以可能每个DLL名称单独一行。 因此,正确的配置可能是在IncludeAssemblies节点下,每行一个DLL名称,使用正则表达式匹配。例如: <IncludeAssemblies> ^A$ ^B$ </IncludeAssemblies> 这样,只有精确匹配A和B的DLL会被包含。而默认情况下,Costura可能排除其他所有未被包含的DLL。 需要验证这种配置是否有效,或者是否需要同时设置ExcludeAssemblies为.*,然后IncludeAssemblies覆盖。但根据Costura的文档,IncludeAssemblies会覆盖默认的包含所有的行为,从而只包含指定的DLL。因此,正确的配置应该是使用IncludeAssemblies列出所有需要包含的DLL,而其他未被列出的则不会被包含。 因此,最终的步骤应该是用户创建FodyWeavers.xml文件,配置IncludeAssemblies节点,并列出所需的DLL名称,每个名称占一行,使用正则表达式确保精确匹配。</think>要在C#项目中使用Costura.Fody仅嵌入指定的DLL文件,可通过配置`FodyWeavers.xml`文件实现。以下是具体步骤: ### 1. 安装Costura.Fody 通过NuGet安装Costura.Fody包。对于.NET Framework项目,建议选择4.1.0版本[^3]: ```powershell Install-Package Costura.Fody -Version 4.1.0 ``` ### 2. 配置FodyWeavers.xml 在项目根目录下创建(或修改)`FodyWeavers.xml`文件,使用`IncludeAssemblies`或`ExcludeAssemblies`节点控制嵌入的DLL: ```xml <?xml version="1.0" encoding="utf-8"?> <Weavers> <Costura> <!-- 仅包含指定DLL --> <IncludeAssemblies> ^YourDllName1$ <!-- 使用正则表达式匹配DLL名称(不含扩展名) --> ^YourDllName2$ </IncludeAssemblies> <!-- 或排除其他DLL --> <ExcludeAssemblies> ^ExcludedDll1$ <!-- 排除不需要嵌入的DLL --> ^ExcludedDll2$ </ExcludeAssemblies> </Costura> </Weavers> ``` ### 3. 配置说明 - **包含特定DLL**:在`IncludeAssemblies`中列出目标DLL名称(正则表达式格式),仅这些DLL会被嵌入。例如`^Newtonsoft.Json$`会嵌入`Newtonsoft.Json.dll`[^1]。 - **排除特定DLL**:若需排除部分DLL使用`ExcludeAssemblies`节点,其余DLL默认嵌入。 - **混合配置**:可同时使用两个节点,优先执行`Include`再执行`Exclude`。 ### 4. 非托管DLL的特殊处理 对于非托管DLL(如`SQLite.Interop`),需单独配置[^2]: ```xml <Costura> <Unmanaged32Assemblies>SQLite.Interop</Unmanaged32Assemblies> <Unmanaged64Assemblies>SQLite.Interop</Unmanaged64Assemblies> </Costura> ``` ### 验证配置 构建项目后检查输出目录: - 若配置正确,目标DLL会被嵌入EXE,且输出目录中不再包含这些DLL。 - 运行时若触发`AssemblyResolve`事件,会从EXE资源中提取DLL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值