System.Data.Sqlite.dll以P/Invoke方式调用原生SQLite.Interop.dll(32位与64位系统不同)动态链接库,因此无法通过的方式来编译程序,索性大多数人直接将程序编译为x86(毕竟64位操作系统照样运行32位程序不是?),但这也是长期困扰强迫症儿童们的一个问题,CSDN上也出现过不少AnyCPU解决方案:
纵观以上所有方案,思路完全一致,都是通过Marshal.SizeOf(typeof(IntPtr))或sizeof(IntPtr)判断当前操作系统位数,释放或切换相应的SQLite.Interop.dll。将32位、64位的原生DLL分别放到x86和x64目录,其实也是以前官方提供过的做法,最可气的是大家都很有默契地设置下载
50积分
,无奈本人还一个个地下载研究,一次次地大失所望,最后看着自己的积分再也下载不起......
8年前,GitHub上出现过一个牛逼的项目
csharp-sqlite
,作者将SQLite的源码翻译成C#了,根本就不需要SQLite.Interop.dll,也就不存在无法AnyCPU的问题了。
十万行代码翻译成C#,工作量不言而喻,关键是很多地方无法直译,如何将指针、结构体转换成对象很难,而C语言中大段大段的字符串处理放到C#中可能只要几行代码,如何正确理解原作的意图更难。情理之中,这个项目能够编译成功,但在处理SQL语句时出问题了,而作者只是将源码传上来,然后就没有然后了......
就在我撸起袖子,准备继续csharp-sqlite项目时,忽然想到一个问题,一旦sqlite升级了怎么办?是不是得再来一次?原作者可能就是因为这个才不去更新的吧?在这个浮躁的年代,我觉得还是得给自己找足理由再去干活。
为什么要编译成AnyCPU平台呢?是SQLite不能在x86或x64平台下工作吗?显然不是,直接编译为x86平台,什么问题都没有,SQLite.Net的bundle版甚至将托管与非托管代码编译成了一个DLL,如果不去深入探究,大多数人都不会发现这是一个很牛逼的动态链接库。
等等,“牛逼”?对了,用SQLite还要AnyCPU不就是为了“牛逼”吗?确切地说应该是为了“装逼”,
http://www.360doc.com/content/20/0116/10/64300317_886466613.shtml
。理由好像不太充分,为什么呢?……
或许,我们并不是仅仅想让引用了System.Data.SQLite的.Net程序能够运行在32位和64位操作系统这么简单,更多的可能是想让它能够和不使用SQLite的程序一样能够不在任务管理器的进程列表中多显示一个*32。或许,是想用ILMerge将exe和DLL成一个文件作为一个纯绿色软件......;或许,就是单纯地不想让别人看到我们使用了SQLite数据库。概括起来就是,需要一个编译为AnyCPU的System.Data.SQLite.dll且能够从内存加载该程序集,相应地SQLite.Interop.dll也应该从内存加载,这就涉及到内存加载运行DLL的知识。
内存加载运行DLL,CSDN上也有很多
我们只要将32位和64位的SQLite.Interop.dll作为资源嵌入到System.Data.SQLite.dll中,根据运行平台将对应版本拷贝到内存并运行,将原先通过P/Invoke的调用修改为通过委托调用,如将
[DllImport(SQLITE_DLL)]
internal static extern IntPtr interop_compileoption_get(int N);
internal delegate IntPtr interop_compileoption_get_delegate(int N);
internal static interop_compileoption_get_delegate interop_compileoption_get;
通过静态构造,将interop_compileoption_get指向DLL中的interop_compileoption_get函数:
string platform = Marshal.SizeOf(typeof(IntPtr)) == 8 ? "x64" : "x86";
dllLoader = new DllLoader(typeof(UnsafeNativeMethods).Assembly.GetManifestResourceStream("System.Data.SQLite.Resources." + platform + ".interop"));
interop_compileoption_get = dllLoader.GetProcDelegate<interop_compileoption_get_delegate>("interop_compileoption_get");
DllLoader的实现并不复杂,难在兼容32位和64位,毕竟两个平台下的PE格式略有不同,所幸已经让我解决了,System.Data.SQLite.dll已经修改完毕,特地写了一个简单的SQLite管理小工具,纯绿色版的(将System.Data.SQLite.dll作为exe文件的嵌入资源,将SQLite.Interop.dll作为System.Data.SQLite.dll的嵌入资源,不需要任何依赖库即可运行),运行后也不释放任何文件。
https://download.csdn.net/download/caojinrong/16632892
System.Data.Sqlite.dll以P/Invoke方式调用原生SQLite.Interop.dll(32位与64位系统不同)动态链接库,因此无法通过的方式来编译程序,索性大多数人直接将程序编译为x86(毕竟64位操作系统照样运行32位程序不是?),但这也是长期困扰强迫症儿童们的一个问题,CSDN上也出现过不少AnyCPU解决方案: 纵观以上所有方案,思路完全一致,都是通过Marshal.SizeOf(typeof(IntPtr))或sizeof(IntPtr)判断当前操作系...
System.Data.Sqlite.DLL 1.0.94.0
Sqlite 3.8.6
现提供一个以资源方式存到System.Data.SQLite.dll中的动态库。在运行中自动释放SQLite.Interop.dll并根据当前运行进程位数进行调用。
支持项目生成时选择为AnyCPU(不受32位系统与64位系统的限制)
已完善为自动检测当前系统位数,本次程序运行只释放对应位数的SQLite.Interop.dll
在只装有.NET2.0的机器上就可以操作Sqlite数据库。
实测32(XP,2003)位系统与64(2003,WIN7,Win8)位系统均正常执行。
之所以将释放的文件放在10940_x86或10940_x64下面是为了同一目录下支持运行不同版本的Sqlite(一般很少见),如果文件已经存在,则对比文件的MD5值,不一样则进行覆盖(如果不同版本,这样就会出错了)。
资源包中有三种类型编译成功的程序分别为X86/X64/AnyCPU,实现一个简单的操作,写入数据1万行。(还附上了从官网下载的原版程序用于没有装C++运行环境的对比)
亲测有效,System.Data.SQLite.dll文件及教程,不需要下载nuget包
System.Data.Sqlite.dll分32位和64位版本,在编译程序的时候需要注意引用。
引用方法(见笑了):在项目中添加现有文件(添加库文件的版本需要生成的可执行文件的版本对应,anyCPU添加32位版本的即可)SQLite.Interop.dll和System.Data.SQLite.dll(这两个动态库的属性》复制到输出目录设置为“始终复制”或“如果较新则复制”),在项目引用中添加引用System.Data.SQLite.dll(浏览》找到动态库文件》添加即可)
————————————————
版权声明:本文为CSDN博主「wu_pan123」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wu_pan123/article/details/107423285
Sqlite 3.8.6
现提供一个以资源方式存到System.Data.SQLite.dll中的动态库。在运行中自动释放SQLite.Interop.dll并根据当前运行进程位数进行调用。
支持项目生成时选择为AnyCPU(不受32位系统与64位系统的限制)
已完善为自动检测当前系统位数,本次程序运行只释放对应位数的SQLite.Interop.dll
在只装有.NET2.0的机器上就可以操作Sqlite数据库。
实测32(XP,2003)位系统与64(2003,WIN7,Win8)位系统均正常执行。
之所以将释放的文件放在10940_x86或10940_x64下面是为了同一目录下支持运行不同版本的Sqlite(一般很少见),如果文件已经存在,则对比文件的MD5值,不一样则进行覆盖(如果不同版本,这样就会出错了)。
资源包中有三种类型编译成功的程序分别为X86/X64/AnyCPU,实现一个简单的操作,写入数据1万行。(还附上了从官网下载的原版程序用于没有装C++运行环境的对比)
在VisualStudio中项目平台属性包含x86/x64/AnyCPU三个选项,之前的项目中并没有特别去关注这一点,最近的项目中涉及到了在不同平台运行的问题,所以专门了解并整理了这方面的知识。x86/x64/AnyCPU的含义在vs中这一选项被称为“目标平台”,也就是编译成功的项目最终是要在什么平台上运行。 编译(目标)平台
含义 x86
将程序集编译为由兼容 x86 的 32 位公
亲测有效,感谢原创作者!
在C#中如果要使程序自适应32位和64位系统,只需要将项目的“目标平台”设置为“Any CPU”就行了,但是如果程序中使用了SQLite组件,则需要对该组件额外进行一些简单的设置:
一、下载System.Data.SQLite组件:
从官网(h...
一.Sqlite资源链接:
(1)Wz132 Sqlite官网:可以从官网下载源码、或下载已经编译好的二进制版本。支持的系统包括:Linux、MacOS、Windows、.NET。
(2)SqliteStudio:好用的Sqlite可视化管理器。
二.在.NET中使用Sqlite
从官网下载.NET版本的Sql
之所以要做这个笔记,是因为在.NET中使用System.Data.SQLite的时候,遇到了些问题,这些问题是相对于引用其他dll没有遇到过的,所以作个笔记,记录一下。
简单起见,首先建立一个控制台项目,这肯定是.NET4.5以上的版本了,我用的是vs2017,其他版本的vs在引用System.Data.SQLite的时候有没有问题,这个就不得而知了。
首先还是按照以往使用第三方dll文件(指...
在Sqlite官网上下载下来的最新版System.Data.SQLite.dll与SQLite.Interop.dll(X85与X64)需要安装安装对应的Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package(X64与X86)才能正常调用,这样给打包带来了一定麻烦。现提供一个以资源方式存到System.Data.SQLite.dll中的动态库。在运行中自动释放SQLite.Interop.dll并根据当前运行进程位数(官方已实现)进行调用。
最大的靓点为只要在装有.NET2.0的机器上就可以操作Sqlite数据库。
实测32(XP,2003)位系统与64(2003,WIN7,Win8)位系统均正常执行。
TEST1.EXE中写了一个简单的操作,写入数据1万行。