如何根据外部资源有条件地以 64 位或 32 位模式运行程序?



论坛上到处都是关于提供程序未在本地计算机上注册Microsoft.ACE.OLEDB.12.0问题(和不需要的答案),就像这个一样。问题的要点,我如何理解它,是应用程序将在与运行应用程序相同的平台上查找提供程序。因此,如果您的计算机是 64 位,提供程序是 32 位,那么如果您不编译应用程序以在 32 位模式下运行,就会出现不匹配。

大多数答案通过为当前平台安装适当的数据组件来有效地解决这个问题。其他建议是针对数据组件可用的平台进行编译。

我正在使用运行 Windows 7、8 和 10 的 PC 开发一个应用程序,所有 64 位,具体取决于我所在的位置,但有些具有较旧版本的 Office,而另一些则具有较新版本。这导致我不得不根据我当前使用的 PC 更改我编译的平台。虽然这对我来说没有问题,但就我个人而言,我预见到这会给无法运行该程序的最终用户带来麻烦。

尽量避免要求用户在其计算机上安装其他组件;有没有办法告诉程序检查数据库提供程序的平台可用性,然后在该模式下运行?是否可以创建数据库模块的 32 位和 64 位扩展并加载适当的扩展,而不管主程序以何种模式运行?

编辑:

我只是尝试在不同的平台上编译我的数据库扩展,无论哪个平台与应用程序不是同一平台,在加载时都会发生异常,说我正在尝试从不同的平台加载程序集。所以我想我的选项 2 不走运......

您可以使用 CorFlags 实用程序在检测需要运行的模式后修改目标计算机上的可执行文件。

首先,确保您的主 exe 是在未设置Prefer 32 bit标志的任何 CPU 下编译的。现在,当应用程序启动时,您需要检查我们是否处于 64 位进程中,并检查您的依赖项(我不会介绍 - 我不使用 OLEDB)。如果您发现不匹配(假设您在 64 位进程中运行,但您的依赖项是 32 位) - 您需要运行外部进程来修改主可执行文件,然后重新启动它。最简单的方法是通过简单的cmd脚本,如下所示(在此示例中,我的主exe称为ConsoleApplication3.exe):

:start
start /wait "" "C:Program Files (x86)Microsoft SDKsWindowsv10.0AbinNETFX 4.6.1 ToolsCorFlags.exe" ConsoleApplication3.exe /32BIT+
if errorlevel 1 (
goto start
)
start "" ConsoleApplication3.exe

请注意,这只是示例,如果出现问题,它将陷入无限循环,请根据您的要求进行调整。此脚本的作用只是使用 CorFlags 工具更新您的 exe 以在 32 位模式下运行,然后启动您的主 exe。

启动应用程序后,您可以立即执行以下检查:

static void Main() {
if (Environment.Is64BitProcess) {
// here you also check if you have dependency mismatch, and then:
Console.WriteLine("Running in 64-bit mode. Press any key to fix");
Console.ReadKey();
// run script (here we assume script is in the same directory as main executable, and is called fix-mode.cmd
var process = new Process() {
StartInfo = new ProcessStartInfo("cmd.exe", "/c call fix-mode.cmd")
};
process.Start();                
// here you should exit your application immediatly, so that CorFlags can update it (since it cannot do that while it is running)
}
else {
// after restart by our script - we will get here
Console.WriteLine("Running in 32bit mode");
}
}

请注意,此工具(CorFlags)仅适用于Visual Studio,因此您可能希望将其与应用程序打包在一起(可能在远程计算机上不可用)。

最新更新