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

简介: 我在 VS2017 上使用 C-Sharp 来定位 64 位 Win10 机器上的 Sqlite3 文件。框架使用是4.5,因此可以掌握与 Win7 的迁移。客户端也没有想释放的拆分版本,所以产品必须支持“任何CPU”。

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

目标平台:任何 CPU

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

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

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

重复! 重复! 重复

客户端不希望使用 NuGet 包。因为这个项目不包括第 3 方参考处理。

我该如何解决这个问题? 这样我的表格,使用方法:

SQLiteConnection(连接字符串)

SQLiteDataReader

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

更新

这是执行的底层代码,导致“任何 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);

        } 


德玛西亚99
浏览 282回答 1
1回答

哔哔one

您可以使用System.Data.SQLite 网站上描述的本机库预加载功能:如果开发机器和客户机器可能具有不同的处理器架构,则可能需要多个二进制包。对于这种情况,强烈建议使用本机库预加载功能。它从 1.0.80.0 版本开始可用,并默认启用。为了利用此功能,必须将单独的托管程序集和互操作程序集与 XCOPY 部署一起使用(即混合模式程序集不支持此功能,也不支持将程序集部署到全局程序集缓存),从而导致一个看起来像这样的应用程序部署:&nbsp;<bin>\App.exe&nbsp;(可选的,仅托管的应用程序可执行程序集)<bin>\App.dll&nbsp;(可选的,仅限托管的应用程序库程序集)<bin>\System.Data.SQLite.dll&nbsp;(必需的,仅限托管的核心程序集)<bin>\System.Data.SQLite.Linq.dll&nbsp;(可选的,仅限托管的 LINQ 程序集)<bin>\System.Data.SQLite.EF6.dll&nbsp;(可选,仅限托管的 EF6 程序集)<bin>\x86\SQLite.Interop.dll&nbsp;(必需,x86 本机互操作程序集)<bin>\x64\SQLite.Interop.dll&nbsp;(必需,x64 本机互操作程序集)<bin>上面的字符串“&nbsp;”表示应用程序二进制文件要在目标机器上部署的目录。启用本机库预加载功能和上面显示的应用程序部署后,System.Data.SQLite 仅托管程序集将尝试自动检测当前进程的处理器架构并预加载适当的本机库。关于如何在没有 Nuget 包的情况下使用预加载功能的分步说明。删除System.Data.SQLite.dll您在项目中的所有副本,并确保System.Data.SQLite.dll在您的系统上的全局程序集缓存中没有注册。在您的项目文件夹中,添加一个名为“x64”的子文件夹和一个名为“x86”的子文件夹。为了使用它,您必须从 System.Data.SQLite 网站下载两个 ZIP 存档。下载“用于 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.zipSystem.Data.SQLite.dll将此 zip文件中的文件复制到您的项目文件夹中。将文件复制SQLite.Interop.dll从这个zip以下项目文件夹x64文件夹。下载“用于 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文件夹。在您的 Visual Studio 项目中,将这三个文件添加为项目的链接,使其如下所示:在您的 Visual Studio 项目中,选择这三个文件并将它们的属性“复制到输出目录”设置为“始终复制”。在您的 Visual Studio 项目中,在引用下,删除对 System.Data.SQLite 的引用(如果已经存在),而是添加对复制到项目目录中的 System.Data.SQLite.dll 的引用。将属性“特定版本”设置为 true。构建项目。您现在将在输出目录中看到此文件结构,并且无论应用程序是在 32 位还是 64 位模式下运行,一切都将按预期工作。为了分发应用程序,必须分发这三个 dll,同时保持相同的文件结构,并且不在全局程序集缓存中注册 DLL。静态链接的变体:请注意,按照上述步骤,您还必须在客户电脑上分发 Microsoft 的“Visual C++ 2012 Update 4 运行时”的 x86 和 x64 版本。如果您不这样做,则在第 4 步和第 5 步中下载标记为“预编译静态链接二进制文件”的 ZIP 文件。唯一的区别在于如何SQLite.Interop.dll在这个变体中编译命名的两个文件。背景说明:您可以下载 System.Data.SQLite.dll 的两种不同变体:混合模式有混合模式变体。在这个变体中,这个相同的 dll (System.Data.SQLite.dll) 包含实际的非托管 SQLite 源代码以及托管的 .net 包装器。混合模式程序集(因为它们包含非托管本机代码)在编译期间绑定到 32 位或 64 位环境。因此,混合模式 System.Data.SQLite.dll 有 32 位版本,混合模式 System.Data.SQLite.dll 有 64 位版本。当您引用这两个混合模式程序集中的任何一个时,您的应用程序只能在 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 位),并将它们都安装在您的开发机器和客户计算机上的全局程序集缓存中。然后,您的应用程序将在运行时自动从全局程序集缓存中选择具有正确处理器架构的版本。
打开App,查看更多内容
随时随地看视频慕课网APP