Cannot encrypt / decrypt SQLite database in .NET4

2019-07-26 06:58发布

问题:

I am running Visual Studio 2010 on a Windows 7 x64. The app I'm writing is supposed to run on all platforms (AnyCPU). I'm able to encrypt/decrypt the database file if I'm using the System.Data.SQLite.dll either x86 version (sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0.zip) or x64 one (sqlite-netFx40-static-binary-bundle-x64-2010-1.0.77.0.zip).

I need my app to run on both platforms x86 and x64 (Any CPU project build setting). I've tried installing the ADO.NET 4.0 Provider (SQLite-1.0.67.1-vs2010-net4-setup.exe). I added the reference (right-click on project, Add Reference, .NET tab -> System.Data.SQLite) and ran the program. If I decrypt the file and try to encrypt by calling ChangePassword("myPass"), I get the following exception:

System.EntryPointNotFoundException was caught

Message=Unable to find an entry point named 'sqlite3_rekey' in DLL 'System.Data.SQLite.DLL'. Source=System.Data.SQLite TypeName="" StackTrace:

   at System.Data.SQLite.UnsafeNativeMethods.sqlite3_rekey(IntPtr db, Byte[ key, Int32 keylen)
   at System.Data.SQLite.SQLite3.ChangePassword(Byte[ newPasswordBytes)
   at System.Data.SQLite.SQLiteConnection.ChangePassword(Byte[ newPassword)
   at System.Data.SQLite.SQLiteConnection.ChangePassword(String newPassword)
   at SQLiteTest.Database.Encrypt() in C:\SQLiteTest\Database.cs:line 166

Also, I've tried to open a connection using the SQLiteConnection object and I get two different exceptions in two different cases. First, if the file is encrypted and I don't specify a password in the connection string I get this:

System.Data.SQLite.SQLiteException was caught Message=File opened that is not a database file file is encrypted or is not a database
Source=System.Data.SQLite ErrorCode=-2147467259 StackTrace: at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous,

UInt32 timeoutMS, String& strRemain) at System.Data.SQLite.SQLiteCommand.BuildNextCommand() at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index) at System.Data.SQLite.SQLiteDataReader.NextResult() at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave) at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery() at System.Data.SQLite.SQLiteConnection.Open() at SQLiteTest.Database.GetAllLanguages() in C:\SQLiteTest\Database.cs:line 216

Second, if I add the password parameter to the connection string, I get the System.EntryPointNotFoundException like the one above.

So, does anyone know a sure-fire way to work with encrypted SQLite database in a C# app on AnyCPU platform?

Thanks in advance!

回答1:

Following Solution is a little bit dirty, but it may work, we didn't use encrypted database so i'm not 100% if that will work for you. We downloaded both versions of sqlite dlls for x64 and x86 and placed them in different folders. We load them manually dependent on what platform application is currently running ( we check IntPtr.Size , from .net 4 there is a property in Environment class called Is64BitOperatingSystem) when we loaded assembly manually we get connection instance with

 var sqliteConnectionType = assembly.GetType("System.Data.SQLite.SQLiteConnection");
 (DbConnection)Activator.CreateInstance(sqliteConnectionType);

we don't use reference to any version of sqlite in our project.