是否可以在PowerShell会话之间传递com对象的实时实例

时间:2015-04-19 20:43:00

标签: powershell quickbooks

我有一个第三方应用程序,到目前为止使用插件与quickbooks交谈。该插件不再适用于最新版本的Windows操作系统,因此我将使用PowerShell脚本替换它。插件将实现QBXMLRP.RequestProcessor com对象,然后打开连接并开始与QuickBooks的会话,处理来自我的应用程序的各种请求,然后关闭并断开与quickbooks的连接。连接打开时,QuickBooks提供的票证用于处理来自我的应用程序的任意数量的请求。

使用PowerShell,我执行命令行提示以“PowerShell”启动PowerShell,并运行PowerShell .ps1脚本文件。正如插件所做的那样,PS脚本实例化com对象,打开qb连接,开始qb会话,发送qb请求,结束qb会话,关闭qb连接。

这很好用,除了与插件不同,我在使用QuickBooks的单个打开会话期间无法从我的应用程序发送多个请求。一旦我发出命令行提示符,PS脚本会执行此操作并且PS退出并且com对象丢失。无论如何,他们是保留qb com对象的实时实例并在后续的PowerShell会话中重用它......

我的应用程序发出命令行提示符以运行开始qb会话的PowerShell ...

(.ps1 script)    
$myqbxmrlp = New-Object -com QBXMLRP.RequestProcessor
$myqbxmrlp.OpenConnection(...)
$ticket = $myqbxmrlp.BeginSession(....) 
$ticket | Export-CliXml $ticket (or set-content)
?? preserve the live $myqbxmrlp com object ??

我的应用程序发出命令行调用打开PS Session 2向qb发送请求...

(.ps1 script)    
$myqbxmrlp = ?? get the live com object back ??
$ticket = Import-CliXml $ticket (or get-content)
$myqbxmrlp.ProcessRequest($ticket,....)      

使用另一个请求打开PS Session 3的命令行调用...

使用另一个请求打开PS Session 4的命令行调用...

命令行调用打开PS Session 5并结束qb会话并关闭qb连接...

(.ps1 script)    
$myqbxmrlp = ?? get the com object back ??
$ticket = Import-CliXml $ticket (or get-content)
myqbxmrlp.EndSession($ticket,....)
$myqbxmrlp.CloseConnection

有没有其他方法可以使用PowerShell来解决这个问题?

1 个答案:

答案 0 :(得分:3)

我无法验证这是否适用于QuickBooks,但它可以用于Excel和其他COM对象。您必须使用Marshal.GetActiveObject方法:

# Name of the QuickBooks COM object
$QbComObject = 'QBXMLRP.RequestProcessor'

# Try to get active instance of the QuickBooks COM object
if(-not ($myqbxmrlp = [Runtime.InteropServices.Marshal]::GetActiveObject($QbComObject)))
{
    # If we can't, then create new instance
    $myqbxmrlp = New-Object -ComObject $QbComObject
    $myqbxmrlp.OpenConnection(<#...your code...#>)
}

# Some code to process tickets...
$ticket = $myqbxmrlp.BeginSession(<#...your code...#>) 
$ticket | Export-CliXml $ticket

相关问题:How to connect to existing instance of Excel from PowerShell?

更新#1:

  

如何使Marshal.GetActiveObject可用。我得到了   跟随错误...使用“1”调用“GetActiveObject”的异常   参数:“操作不可用(HRESULT异常:   0x800401E3(MK_E_UNAVAILABLE))“

这可能意味着the 3rd party app is not registered as an automation server. It is not possible to get a reference to the running instance.。您可以尝试注册使用regsvr32.exe公开QBXMLRP.RequestProcessor(可能是dll \ tlb \ ocx \ exe)的文件,但鉴于我对QuickBooks的零知识,我无法给您任何具体的指示。尝试在QuickBooks安装目录中搜索包含字符串RequestProcessor的文件。

更新:#2

虽然您似乎无法获得QuickBooks对象的实时实例,但这可以通过进程间通信(IPC)来缓解:

  1. 一个脚本应创建一个QuickBooks对象,然后等待输入
  2. 所有QuickBooks交互都是通过后续调用另一个脚本来完成的,该脚本只会通过IPC将请求传递给第一个脚本。
  3. IPC可以通过命名管道完成,这里有一些例子: