64-битная PowerShell вызывает 32-битную DLL

На компьютере с Windows 10 я вызываю QuickBooks из базы данных 4-го измерения (4D) с помощью сценария PowerShell. Сценарий вызывает QBXMLRP2.dll, 32-битный COM-объект, для связи с QuickBooks 2019. Насколько я понимаю, если вы вызываете 32-битную dll с помощью 64-битной версии PowerShell, произойдет сбой, и наоборот. Однако я получаю разные результаты в зависимости от того, использую ли я 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/32-битная 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

Насколько я понимаю, 4D исчезает после запуска PowerShell. 4D не взаимодействует с dll. Это все PowerShell/dll (COM)/QuickBooks.

Было бы неплохо посмотреть, как вы получаете доступ к DLL.

montonero 31.05.2019 09:33

Для 4D и DLL 32, powershell 64, я думаю, что DLL не может возвращать дополнительную информацию, и powershell может объяснить это. 64 способен обрабатывать 32, а 4D в любом случае не ожидает 64-битных команд. Однако, когда вы переключаете 4D на 64, powershell может взаимодействовать с ним только с использованием 32-битной версии, поэтому, когда он запускает 64-битную команду powershell и ожидает ответа 64, DLL сокращает ее до 32-битной, вызывая ошибку. С 4D 64, PS и DLL 32 Powershell ожидает всего в 32, поэтому несоответствие между DLL и 4D никогда не проявляется, потому что powershell не пытается отправлять 64-битные команды.

Shadowzee 31.05.2019 09:35

Я обновил пост, чтобы, надеюсь, ответить на ваши вопросы. @Shadowzee Я не уверен, что следую логике твоего ответа. Вы говорите, что PS 64 может работать с 32-битными DLL? Если я попытаюсь запустить скрипт ps вручную в 64-битной версии PowerShell ISE, я получу ошибку «80040154 Class not Registered...», чего я и ожидаю. При запуске формы 4D, если я показываю консоль PowerShell, я вижу красную ошибку, отображаемую все, что нужно для быстрого чтения. Поэтому я почти уверен, что получаю ту же ошибку при запуске 4D.

JohnBDH 31.05.2019 19:47

Я добавил скрипт PowerShell в свой пост.

JohnBDH 31.05.2019 20:32

Позвольте мне перефразировать. Если, когда я запускаю PowerShell из 64-битного 4D с настроенной консолью PS, я вижу красные сообщения об ошибках, отображаемые в консоли, и все это быстро читается. Если я запускаю 64-битный PowerShell из 32-битного 4D, консоль открывается, остается открытой без ошибок в течение нескольких секунд, пока сценарий не завершится успешно. Последнее - то, что я подвергаю сомнению.

JohnBDH 31.05.2019 22:10

Это хороший результат, если бы я собирался использовать 32-битное 4D, но я буду использовать 64-битное 4D. В будущем мне, очевидно, придется использовать 32-битную PowerShell. Если Microsoft когда-нибудь решит отказаться от 32-битной поддержки, я думаю, Intuit предоставит нам 64-битную dll. Однако мне очень интересно, почему это работает при использовании 32-битного 4D.

JohnBDH 31.05.2019 22:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
569
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С помощью этого форума и дополнительных исследований я теперь понимаю, что в 64-битной операционной системе Windows, если ОС обнаружит, что 32-битное приложение выполняет вызов в каталог System32, она автоматически перенаправит вызов в каталог SysWow64. . Таким образом, в моем сценарии 32-битный PowerShell всегда будет запускаться при вызове из 32-битного 4D. Обратите внимание, что это перенаправление работает только в том случае, если вызывающее приложение является 32-разрядным на 64-разрядной машине. Поэтому, если 64-битное приложение (4D) вызывает 64-битную оболочку PowerShell в каталоге System32, перенаправление не произойдет. В этом случае, если PowerShell вызывает 32-битную dll, произойдет сбой. PowerShell/dll должны соответствовать разрядности.

Если кто-то хочет принудительно запустить 64-битную версию в каталоге System32 из 32-битного приложения, можно использовать специальный каталог «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

Другие вопросы по теме