在开发Windows应用程序时,使用C#和SQLite是一种常见的选择。然而,完成开发后,开发者面临的一个问题是如何将应用程序顺利部署到客户机器上。客户机器可能是32位或64位的,如何确保应用程序能够在任何Windows平台上运行,无论它是32位还是64位的?
在互联网上搜索,可以找到许多关于这个话题的零散想法。因此,将这些相关的信息整理成一篇易于理解的文章。
根据参考[1],需要决定下载正确类型的二进制包,因为要考虑如何将应用程序部署到客户机器上。决策过程包括以下步骤:
所有不包含"static"的包都需要在目标机器上安装相应版本的Microsoft Visual C++运行库才能成功。包含"setup"的可下载包已经包括并会尝试自动安装所需的Microsoft Visual C++运行库。这意味着安装程序在目标机器上有更多的工作要做。因此,寻找包含"static"的包。
将下载"static"包,因为这些程序集二进制文件是静态链接到相应版本的Visual C++运行库的。当应用程序部署到客户机器上时,不能假设客户机器上已经安装了必要的Visual C++运行库版本,因为客户可能没有足够的权限。
不考虑"Bundle"包,因为它的目标是将程序集部署到全局程序集缓存(GAC)文件夹。
还需要确定应用程序目标的.NET Framework版本。目前使用Visual Studio 2015,应用程序目标是.NET框架4.5,但客户机器上可能没有安装.NET 4.5框架。为了安全起见,可以下载针对.NET框架4.0的静态链接包,但根据指南:
选择与目标.NET Framework版本相匹配的包是强烈推荐的,决定选择针对.NET框架4.5的版本。
根据[1],知道程序集System.Data.SQLite.dll是仅托管的核心程序集,程序集SQLite.Interop.dll是原生互操作程序集(x32或x64)。
如果将C#应用程序构建为x86程序集,然后在x64 Windows机器上运行它。将遇到一个问题。在客户/目标64位机器上,因为可执行文件启动的过程完全由托管代码组成,它将与机器的本地处理器架构运行,这在64位机器上将是x64。稍后,这将导致包含任何为x86编译的原生代码的程序集(例如"System.Data.SQLite.dll"混合模式程序集,"SQLite.Interop.dll"原生互操作程序集,或"sqlite3.dll"原生库)无法加载,通常会导致抛出BadImageFormatException,基于[1]。
对于这种x86构建场景,将使用原生库预加载功能,它从版本1.0.80.0开始可用,默认情况下是启用的。
基于上述原因,如果想要应用程序针对任何CPU,将使用以下两个包:
包1: 预编译的32位Windows的静态链接二进制文件(.NET Framework 4.5) sqlite-netFx45-static-binary-Win32-2012-1.0.101.0.zip(它包含Package 1的x86版本的System.Data.SQLite.dll和SQLite.Interop.dll)
包2: 预编译的64位Windows的静态链接二进制文件(.NET Framework 4.5) sqlite-netFx45-static-binary-x64-2012-1.0.101.0.zip(它包含Package 2的x64版本的System.Data.SQLite.dll和SQLite.Interop.dll)
基于上述考虑,将使用XCOPY将应用程序部署到目标机器上,文件结构如下:
<bin>\App.exe
(必需,托管的应用程序可执行程序集)
<bin>\App.dll
(可选,托管的应用程序库程序集)
<bin>\x86\System.Data.SQLite.dll
(必需,x86托管的核心程序集,来自包1)
<bin>\x86\SQLite.Interop.dll
(必需,x86原生互操作程序集,来自包1)
<bin>\x64\System.Data.SQLite.dll
(必需,x64托管的核心程序集,来自包2)
<bin>\x64\SQLite.Interop.dll
(必需,x64原生互操作程序集,来自包2)
在这部分1中,提出了一个文件结构。在下一篇文章中,将提供一个演示来验证这个概念。如果有更好的想法,请与CodeProject社区成员分享。