64 位 PowerShell 调用 32 位 DLL

64bit PowerShell calls the 32bit DLL

在 Windows 10 计算机上,我使用 PowerShell 脚本从第 4 维 (4D) 数据库调用 QuickBooks。该脚本调用 32 位 COM 对象 QBXMLRP2.dll 与 QuickBooks 2019 通信。据我了解,如果您使用 64 位版本的 PowerShell 调用 32 位 dll,它将失败,反之亦然。但是,根据我使用的是 32 位还是 64 位版本的 4D,我会得到不同的结果。这对我来说毫无意义。这是我的测试结果:

OS  4D  PowerShell  DLL   Result
64  32  32          32    OK
64  32  64          32    OK //According to my research this should not work!

64  64  32          32    OK
64  64  64          32     X //According to my research this is the expected behavior

为什么 64 位版本的 PowerShell/32bit dll 可以与 32 位版本的 4D 一起使用?我真正想要的是让它与 64 位版本的 4D 和 PowerShell 一起工作。

回答问题...这是我正在做的。 4D 首先创建一个 .ps1 脚本文件并将其保存到磁盘,然后在外部进程中启动 PowerShell。例如,这将启动 64 位 PowerShell (Windows 10),PowerShell 将执行之前保存的脚本:

"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -file \""+$ScriptPath+"\""

PowerShell 脚本如下所示:

[String]$requestXML = '<?xml version="1.0" ?>
<?qbxml version="2.0"?><QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CompanyQueryRq requestID="1">
</CompanyQueryRq>
</QBXMLMsgsRq>
</QBXML>'
$myQBXMLRP = New-Object -com QBXMLRP2.RequestProcessor
$myQBXMLRP.OpenConnection2("qb4D","CCFolioPro",1)
$ticket = $myQBXMLRP.BeginSession("C:\Company Files\Cadinha & Co.,LLC.QBW",$myQBXMLRP.qbFileOpenDoNotCare)
$myQBXMLRP.ProcessRequest($ticket, $requestXML) > $env:_4D_OPTION_OUTPUT_STREAM
$myQBXMLRP.EndSession($ticket)
$myQBXMLRP.CloseConnection()
"Stop" > $env:_4D_OPTION_STOP_TOKEN

据我了解,一旦 PowerShell 启动,4D 就不再适用了。 4D 不与 dll 交互。都是 PowerShell/dll (COM)/QuickBooks.

借助本论坛的帮助和更多研究,我现在了解到在 64 位 windows 操作系统中,如果 OS 检测到 32 位应用程序正在调用System32 目录,它会自动将调用重定向到 SysWow64 目录。因此,在我的场景中,当从 32 位 4D 调用时,32 位 PowerShell 将始终 运行。请注意,此重定向仅在调用应用程序在 64 位计算机上为 32 位时才起作用。因此,如果 64 位应用程序 (4D) 在 System32 目录中调用 64 位 PowerShell,则不会发生重定向。在这种情况下,如果 PowerShell 调用 32 位 dll,它将失败。 PowerShell/dll 必须匹配位数。

如果想从 32 位应用程序强制 System32 目录中的 64 位版本到 运行,可以使用特殊的 "Sysnative" 目录而不是 System32 目录。请注意,这是一个虚拟目录。您不会在文件系统中找到它。同样,如果您确实强制使用 64 位 Powershell,而 PowerShell 尝试调用 32 位 dll,它将失败。

下面这篇文章很好读...

https://docs.microsoft.com/en-us/windows/desktop/winprog64/file-system-redirector

这是我修正后的测试图表...

OS  4D  PowerShell  DLL   Result
64  32  32          32    OK
64  32  64-OS->32   32    OK //OS redirected to 32bit PS. Expected behavior!

64  64  32          32    OK
64  64  64          32     X //No redirect. Expected behaviour