C#使用SqlCipher以及使用Costura.Fody合并DLL进EXE
创建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: 路径的形式不合法。