1

当我尝试在“C# - ANY CPU” 中使用具有 32 位和 64 位版本的嵌入式数据库时,如SQLiteSQL Server CE

[ 两者都为其 32 位和 64 位版本提供 XCOPY 部署。

检查以下链接:-sql server ce private installation --XCOPY deployment with sqlite- ]

我注意到,当我们检查“首选 32 位”时,XCOPY 部署不起作用,在这种情况下,进程不是 64 位,但尝试从 x64 文件夹加载 ddl 并崩溃。

如果我们取消选中“首选 32 位”,它会像 64 位一样工作,并且还可以找到正确的 dll。

即使我制作了 x86 项目它也可以在 x86 下找到正确的 ddls。

为什么“首选 32 位”编译选项有这种行为?它是一个错误吗?

4

3 回答 3

3

我可以确认 Hippias Minor 的问题——也让我有些头疼。SQLite 由一个托管库组成,该库选择在运行时加载哪个本机 DLL(来自 x64 或 x86 目录的 SQLite.Interop.DLL)。这样它就不需要嵌入本机库(因此更便携——相同的“xcopy 部署”可以在不同的架构上工作)。这也是通常从 NuGet 安装 SQLite 的方式。

“x86”和“任何 CPU w/首选 32 位”(除了能够在 ARM 上运行)之间的区别在于,第一个将环境变量 PROCESSOR_ARCHITECTURE 设置为“x86”,而第二个将其设置为“AMD64” !此处描述了该问题:PROCESSOR_ARCHITECTURE 在某些 32 位进程中返回 AMD64

因此,SQLite(将其用作启发式)将尝试加载 64 位互操作 DLL 并不幸失败,因为它实际上是作为 32 位进程运行的。

一种解决方法可能是检查 Environment.Is64BitProcess,当它为假时,手动将环境变量更改为“x86”。

于 2013-08-01T12:53:19.933 回答
3

“首选 32 位”的主要目的是通过“CPU Any”设置更好地支持处理器。

来自.NET 4.5 和 Visual Studio 11 的 AnyCPU 的真正含义

那么,“任何 CPU 32 位首选”和“x86”之间的区别仅在于:编译为 x86 的 .NET 应用程序将无法在 ARM Windows 系统上运行,但“任何 CPU 32 位首选”应用程序将无法运行将成功运行。

在 x64 处理器上设置此选项与使用 x86 编译选项基本相同。

于 2013-07-25T20:50:25.527 回答
2
if (!Environment.Is64BitProcess
      && Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
          .Equals("AMD64", StringComparison.InvariantCultureIgnoreCase))
{
// Workaround the "Any CPU" w/ "Prefer 32-bit" option from .NET 4.5+
  Environment.SetEnvironmentVariable("PROCESSOR_ARCHITECTURE", "x86");
}

在任何 SQLite 代码似乎使事情起作用之前。

于 2013-08-01T13:01:53.013 回答