4

根据Akavache的平台特定说明:

.NET 4.5 桌面 (WPF) - 您必须将应用程序标记为 x86,否则您将收到关于 SQLitePCL_Raw 未正确加载的奇怪运行时错误。

现在,我只是尝试使用仿照 Akavache Github 页面上的示例代码建模的简单代码在LINQPad中测试 Akavache。

async void Main()
{
    BlobCache.ApplicationName = "JonTestApp1";
    var dt = DateTime.Now;
    await BlobCache.UserAccount.InsertObject("Test1", dt);
    var toaster = await BlobCache.UserAccount.GetObject<DateTime>("Test1");
    toaster.Dump();
}

可以预见的是,它正在爆炸。

如何在 LINQPad 中将我的应用程序构建目标标记为 x86?使用 v. 4.53.16,而不是 AnyCPU 版本,只是普通的 beta。我在设置和谷歌中到处找,但找不到任何东西。

谢谢

* 更新 1 *

尝试@Joe Albahari 的建议。 IntPtr.Size确实是4。这是我在第一await行得到的例外:


System.TypeInitializationException: The type initializer for 'NativeMethods' threw an exception. ---> System.Exception: sqlite3.dll was not loaded.
   at SQLitePCL.SQLite3Provider.NativeMethods..cctor()
   --- End of inner exception stack trace ---
   at SQLitePCL.SQLite3Provider.NativeMethods.sqlite3_open_v2(Byte[] filename, IntPtr& db, Int32 flags, Byte[] vfs)
   at SQLitePCL.SQLite3Provider.SQLitePCL.ISQLite3Provider.sqlite3_open_v2(String filename, IntPtr& db, Int32 flags, String vfs)
   at Akavache.Sqlite3.Internal.SQLiteConnection..ctor(String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks)
   at Akavache.Sqlite3.Internal.SQLiteConnection..ctor(String databasePath, Boolean storeDateTimeAsTicks)
   at Akavache.Sqlite3.SQLitePersistentBlobCache..ctor(String databaseFile, IScheduler scheduler)
   at Akavache.Sqlite3.Registrations.c__DisplayClass6.b__2()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at Akavache.Sqlite3.Registrations.c__DisplayClass6.b__3()
   at Splat.ModernDependencyResolver.GetService(Type serviceType, String contract) in z:\code\paulcbetts\splat\Splat\ServiceLocation.cs:line 223
   at Splat.DependencyResolverMixins.GetService[T](IDependencyResolver This, String contract) in z:\code\paulcbetts\splat\Splat\ServiceLocation.cs:line 138
   at Akavache.BlobCache.get_UserAccount()
   at UserQuery.d__0.MoveNext() in c:\Users\jcomtois\AppData\Local\Temp\LINQPad\_qizvxzkh\query_rjuuom.cs:line 45

由于我通过 LINQPad 的 NuGet 安装了 Akavache,因此我不得不进行一些搜索以找出 sqlite3.dll 的位置。我在 Akavache NuGet 包中(在我的 AppData/Local/LINQPad/Nuget... 中)发现了大约 15 个不同的 slqlite3.dll,用于各种构建。我尝试先将 x86 文件夹中的那个复制到 LINQPad 目录,但同样的错误。然后我尝试将其他每个 sqlite3.dll 复制到 LINQPad 文件夹,但结果仍然相同。

我无法在这台机器上安装 Visual Studio,所以我希望有办法让它与 LINQPad 一起工作。

4

3 回答 3

2

在对此基本上永远感到沮丧之后,我梳理了 sqlite3_raw 依赖项并发现了这一点:

private static bool TryLoadFromDirectory(string dllName, string baseDirectory)
{
    /* snip */

    var architecture = IntPtr.Size == 4 ? "x86" : "x64";
    var dllPath = System.IO.Path.Combine(baseDirectory, architecture, dllName);
    if (!System.IO.File.Exists(dllPath))
    {
        return false;
    }

   /* snip - loads the dll */
}

一旦我将 sqlite3.dll 移动到“{linqpad}\x86\sqlite3.dll”,它就可以正常工作。

于 2015-04-29T05:04:04.393 回答
1

@rdavisau 的回答让我走上了正确的道路,最终弄清楚了这一点。他的解决方案对我不起作用。此答案中的 Akavache 4.1.0 和 LINQPad 4.55.03。

帮助我的源代码在这里

一旦我看到它TryLoadFromDirectory被调用new Uri(AppDomain.CurrentDomain.BaseDirectory).LocalPath)作为查找 的位置sqlite3.dll,我就可以通过在该代码行上调用 a 来查看该位置在 LINQPad 中的位置.Dump()

目前对我来说,是C:\ProgramData\LINQPad\Updates40\455\。这有点不幸,因为每次 LINQPad 自动更新它都会转到不同的目录。

因此x86,我在刚刚找到的那个目录中创建了一个目录,然后尝试sqlite3.dll从 NuGet 包中将其放入其中。我不得不从 LINQPad 的 NuGet 缓存中找到它。我确定在这里找到了适合我的正确的:C:\Users\jcomtois\AppData\Local\LINQPad\NuGet\akavache.sqlite3\SQLitePCL.raw_basic.0.7.0\build\native\sqlite3_dynamic\winxp\x86\sqlite3.dll.

所以现在我认为我有合适的 .dll 供我的测试 LINQPad 程序工作。我运行了它,然后得到了The Program can't start because MSVCR110.dll is missing from your computer. Try reinstalling the program to fix this problem. Ugh 的提示。请记住,这台机器没有安装 Visual Studio。我去这里下载并安装了可再发行组件。

我再次运行了我的测试代码(在执行“取消所有线程并重置”之后)。成功!

一旦这工作,我尝试将x86具有权利的文件夹放在sqlite3.dllLINQPad 安装目录中,但这不起作用。我认为这就是@rdavisau 在他的回答中所指的,因为不清楚。

在 LINQPad 中运行 Akavache 是一种考验,我希望它更容易,但这可能的。

于 2015-04-29T15:47:38.197 回答
0

LINQPad 的 X86 构建始终在 32 位进程中运行您的查询。

您可以通过运行以下查询来验证这一点:

IntPtr.Size

如果返回 4,则您处于 32 位进程中。

您提到您的库使用 SQLite。如果是这样,问题可能是 CLR 无法解析其本机 DLL。尝试将 SQLite 的本机 DLL 复制到 LINQPad 文件夹中(您可以为此目的创建一个带有 LINQPad.exe 副本的特殊文件夹)。

于 2015-02-04T03:59:11.623 回答