使用多个文件中的任何CPU(x64 / x86)

时间:2018-09-09 14:08:10

标签: c# sqlite

简介: 我正在VS2017上使用C-Sharp来定向64位Win10计算机上的Sqlite3文件。 框架用法为 4.5 ,因为可以轻松地进行Win7迁移。 客户端想要发行版本的拆分版本,因此该产品必须支持“任何CPU”。

错误参考: '无法加载文件或程序集' System.Data.SQLite.dll '或其依赖项之一。 '

目标平台:任何CPU

错误原因(在这种情况下):DLL文件针对x64系统,而我被迫继续使用“任何CPU”选项。

此外: 我已经从下载了两个SQLite DLL文件 http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki。从那里,我还恢复了SQLite3的准确源文件。但是,集成的最终结果是我的“使用”行没有“看到”包含SQLite源文件的Filehandler文件夹。

这个一个重复的问题,我看到了从NuGet包到引用“ myapp.exe / x86 / sqlite3.data.dll”和“ myapp”行的多个响应的解决方案.exe / x64 / sqlite3.data.dll”,而未标识在其中插入这些行的应用程序文件位置。让人想知道它们将如何在类文件中被引用。
动态结果表明,使用DLLImport,您可以将方法(即MYSQLConnector)重建为方法。尽管那时我怀疑班级里有很多重复,但在加载项目时有一些客户端要求,例如Windows版本读取。

repeatrepeatrepeat

客户端不希望使用NuGet软件包。由于该项目不包括第三方参考处理。

我该如何解决? 这样我的表单,使用方法:

  

SQLiteConnection(connectionString)

  

SQLiteDataReader

可以与“任何CPU”选项一起使用。

更新

这是执行的基础代码,导致“ Any CPU”的优先级为

void doWork(string path) {
            string valueFound = "";
            if (!System.IO.File.Exists(path)) throw new System.IO.FileNotFoundException("Cant find file", path);

            var connectionString = "Data Source=" + path + ";pooling=false";
            using (var conn = new SQLiteConnection(connectionString))
            {
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "SELECT value FROM values WHERE value = ''";
                    conn.Open();
                    using (SQLiteDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            valueFound = (String)reader["value1"];
                        });
                    }
                }
            }
            MessageBox.Show("We have a value: " + valueFound);
        } 

1 个答案:

答案 0 :(得分:2)

您可以使用the System.Data.SQLite website中所述的本机库预加载功能:

  

如果开发机器和客户机器可能具有不同的处理器   在架构上,可能需要多个二进制包。为了这   情况下,使用本机库预加载功能非常有用   推荐的。从1.0.80.0版本开始可用,并通过以下方式启用   默认。为了利用此功能,   XCOPY部署必须使用托管和互操作程序集   (即,混合模式程序集不支持此功能,   程序集部署到全局程序集缓存时),结果   在看起来像这样的应用程序部署中:

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

上面的字符串“ <bin>”代表目录   应用程序二进制文件将部署在目标计算机上。用   启用本机库预加载功能和应用程序   上面显示的部署中,System.Data.SQLite仅托管程序集   将尝试自动检测该处理器的架构   当前进程并预加载适当的本机库。


有关不使用Nuget软件包如何使用预加载功能的分步说明。

  1. 删除项目中所有System.Data.SQLite.dll的所有副本,并确保系统上的Global Assembly Cache中没有注册System.Data.SQLite.dll

  2. 在“项目”文件夹中,添加一个名为“ x64”的子文件夹和一个名为“ x86”的子文件夹。

  3. 要使用此功能,必须从System.Data.SQLite网站下载两个ZIP存档。

  4. 下载“ 64位Windows的预编译二进制文件(.NET Framework 4.5)”下列出的第二个ZIP文件,该文件中不会显示“混合模式”。目前,这是http://system.data.sqlite.org/downloads/1.0.109.0/sqlite-netFx45-binary-x64-2012-1.0.109.0.zip

将文件System.Data.SQLite.dll从此zip复制到您的项目文件夹中。 将文件SQLite.Interop.dll从此zip复制到项目文件夹下面的x64文件夹中。

  1. 下载“ 32位Windows的预编译二进制文件(.NET Framework 4.5)”下列出的第二个ZIP文件,该文件中不会显示“混合模式”。目前。这是http://system.data.sqlite.org/downloads/1.0.109.0/sqlite-netFx45-binary-Win32-2012-1.0.109.0.zip

将文件SQLite.Interop.dll从此zip复制到项目文件夹下面的x86文件夹中。

  1. 在Visual Studio项目中,将这三个文件添加为项目的链接,以使它看起来像这样:

enter image description here

  1. 在Visual Studio项目中,选择这三个文件并将其属性“复制到输出目录”设置为“始终复制”。

  2. 在Visual Studio项目的引用下,删除对System.Data.SQLite的引用(如果已存在),而是添加对复制到项目目录中的System.Data.SQLite.dll的引用。将属性“特定版本”设置为true。

  3. 构建项目。

  4. 您现在将在输出目录中看到此文件结构,并且无论应用程序以32位还是64位模式运行,一切都将按预期运行。

enter image description here

  1. 要分发应用程序,必须分发这三个dll并保持相同的文件结构,并且不要在全局程序集缓存中注册这些dll。

静态链接的变体:

请注意,按照上述步骤,您还必须在客户PC上分发Microsoft的x86和x64版本的“ Visual C ++ 2012 Update 4运行时”。如果不这样做,请下载标记为“预编译的静态链接的二进制文件”的ZIP文件,而不是在步骤4和5中进行下载。

唯一的区别在于,在此变体中如何编译名为SQLite.Interop.dll的两个文件。


背景说明:

您可以下载System.Data.SQLite.dll的两个不同变体:

混合模式

混合模式变体。在此变体中,该相同的dll(System.Data.SQLite.dll)包含实际的非托管SQLite源代码以及托管.net包装器。混合模式程序集(因为它们包含不受管的本机代码)在编译期间绑定到32位或64位环境。因此,存在32位版本的混合模式System.Data.SQLite.dll,也有64位版本的混合模式System.Data.SQLite.dll。

当您引用这两种混合模式程序集中的任何一个时,您的应用程序只能在32位或64位模式下运行。

仅限托管

然后是仅受管理的变体。在此变体中,System.Data.SQLite.dll仅包含托管包装器代码。在此变体中,程序集是ANY CPU程序集。它可以在32位和64位进程中使用。

然后,实际的非托管SQLite代码包含在名为SQLite.Interop.dll的dll中。这是一个本地(非托管,没有.net)dll。有一个32位版本的SQLite.Interop.dll。还有一个64位版本的SQLite.Interop.dll。

System.Data.SQLite.dll的仅托管变体在加载时确定当前进程的处理器体系结构,然后尝试从具有处理器体系结构名称的子目录中加载适当的SQLite.Interop.dll。


使用全局程序集缓存的替代方法

或者,您可以同时获得System.Data.SQLite.dll的混合模式变体的版本(32位和64位),并在开发时将它们都安装在Global Assembly Cache中。机器和客户计算机上。然后,您的应用程序将在运行时从全局程序集缓存中自动选择具有正确处理器体系结构的版本。