14

我正在 VB.net 中开发一个程序,并使用System.Data.SQLite Precompiled Binaries for .NET,但是它不适用于 x64 架构,并且我遇到了经典的文化问题并且没有加载正确的文件。

System.BadImageFormatException: 
Could not load file or assembly 'System.Data.SQLite, Version=1.0.65.0, Culture=neutral,
 PublicKeyToken=db937bc2d44ff139' or one of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'System.Data.SQLite,
 Version=1.0.65.0,
 Culture=neutral, 
 PublicKeyToken=db937bc2d44ff139'

有没有办法只使用一个dll,也许:

  1. 添加一些指令,如#IFDEF(x86 包含部分代码)或 x64 代码
  2. 加入 dll 只制作一个。
  3. 在 VB.net 中引用这个 dll

你认为是其他更好的想法吗,因为我只想编译一个,而不是一个用于 x32 和另一个用于 x64。

例如(32 位):

Private Shared Sub OpenConection(ByRef Conn As SQLite.SQLiteConnection)
    Conn = New SQLite.SQLiteConnection("Data Source=" & System.Environment.CurrentDirectory & "\database.db")
    Conn.Open()
End Sub

Private Shared Sub CloseConection(ByRef Conn As SQLite.SQLiteConnection)
    Conn.Close()
    Conn.Dispose()
    Conn = Nothing
End Sub

Public Shared Function ReturnSelect(ByVal DataTAbleName As String, ByVal sQuery As String, ByVal sWhere As String) As Data.DataTable
    Dim lDT As New DataTable
    Dim lTA As New SQLite.SQLiteDataAdapter
    If DataTAbleName Is Nothing Then Return New DataTable(DataTAbleName)
    Try
        OpenConection(conexion)
        lTA = New SQLite.SQLiteDataAdapter("SELECT " & sQuery & " FROM  " & DataTAbleName & IIf(sWhere <> String.Empty, " WHERE ", "") & sWhere, conexion)
        lTA.Fill(lDT)
    Catch ex As Exception
        Throw ex
    Finally
        CloseConection(conexion)
        lTA.Dispose()
        lTA = Nothing
    End Try
    Return lDT
End Function

如何将其更改为适用于 64 位架构?也许包括 32 和 64 dll 和函数做类似

Try
    Instance = Me
    'Check If Homidom Run in 32 or 64 bits
    If IntPtr.Size = 8 Then _OsPlatForm = "64" Else _OsPlatForm = "32"
    'continue code

Catch ex As Exception
    ' ex.Message
End Try
4

5 回答 5

25

从 .NET 程序集中使用 SQLite 有多种选择。您的第一步是迁移到比古老的 1.0.65 版本更新的东西。当前版本可以从这里下载:http ://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki或通过SQLite NuGet 包

如果您需要能够在 32 位和 64 位下运行,一种选择是使用本机库预加载选项,您可以将本机二进制文件分发到单独的目录中,使其看起来像这样:

  • \App.exe(可选的,仅限托管的应用程序可执行程序集)
  • \App.dll(可选的,仅限托管的应用程序库程序集)
  • \System.Data.SQLite.dll(必需的,仅托管的核心程序集)
  • \System.Data.SQLite.Linq.dll(可选,仅限托管的 LINQ 程序集)
  • \x86\SQLite.Interop.dll(必需,x86 本机互操作程序集)
  • \x64\SQLite.Interop.dll(必需,x64 本机互操作程序集)

另一种选择是构建您的应用程序的两个版本,并在每个版本中引用适当的混合模式程序集。然后你会得到两个版本,但它们更容易处理,因为你不需要额外的子目录和本机 *.Interop.dlls。

在这些情况下,您不需要 32 位和 64 位之间的代码差异或可选编译。从不同的 NuGet 包安装可能会让你最容易开始。

最后一个选择是使用名为 C#-SQLite 的仅托管克隆:https ://code.google.com/p/csharp-sqlite/ 。它是托管 C# 的 SQLite 引擎的一个端口,因此整个事情作为 AnyCPU 运行,并且位数不是问题。

于 2013-10-01T18:40:02.400 回答
6

几年前我遇到了同样的问题,对我来说最好的解决方案是:

  • 下载最新版本的库
  • 在你的 bin 路径中只放System.Data.SQLite.dlland 最终System.Data.SQLite.Linq.dll
  • 将 x86SQLite.Interop.dll库放入c:\Windows\SysWOW64
  • 将 x64SQLite.Interop.dll库放入c:\Windows\System32
  • 将您的项目编译为Any CPU仅引用System.Data.SQLite(将 dll 放入您的 bin 路径中)
  • 请享用

这样,.NET 框架将在运行时自动加载正确的(x86 与 x64)库,而无需在 GAC 或类似中注册任何内容。

希望这可以帮助。

于 2013-10-03T06:46:56.593 回答
1

不,没有。

这是因为这些 *.dll 只是原生 c/c++ *.dll 的包装器。而 32 位 .NET 应用程序必须使用 32 位 c/c++ dll,而 64 位 .NET 应用程序必须使用 64 位 c/c++ dll。

好久没用vb.net了,不知道能不能像c#一样配置目标平台。如果可以,您应该这样做并使用正确的互操作 dll。您应该决定是否需要 32 位或 64 位。

于 2013-10-01T12:47:25.213 回答
1

@Govert 和@TobiaZambon 的其他答案是正确的方法。但对于其他阅读者,另一种选择是使用 x86 版本的 System.Data.Sqlite dll,并且只为 x86 平台编译您的应用程序。即不编译到 AnyCPU,这意味着当它在 x64 机器上运行时,windows 将以 32 位模式运行它,并且能够加载 32 位 dll。

这是否有用取决于您的情况,但如果您正在构建一个部署到工作站的应用程序,这是一个非常简单的解决方案。

于 2015-04-12T21:06:38.527 回答
1

使用Nuget可以轻松解决问题的最新状态 安装后,搜索SQLite ,如下所示:

PM> Install-Package System.Data.SQLite 

我已经使用全新的计算机和 VS 完成了这项工作,我需要 SQLite 并做到了这一点,一切正常。

于 2015-11-25T17:26:13.997 回答