Is it possible to pass a live instance of a com object between PowerShell sessions

I have a third-party application that has so far talked to quickbooks using a plugin. This plugin no longer works with the latest versions of Windows, so I am replacing it with PowerShell scripts. The plugin will create a QBXMLRP.RequestProcessor com object, then open a connection and start a session with QuickBooks, process various requests from my application, and then close and disconnect the connection using quick books. While the connection is open, the ticket provided by QuickBooks is used to process any number of requests from my application.

Using PowerShell, I run a command prompt to launch PowerShell with the PowerShell.ps1 script running. As the plugin did, the PS script creates an instance of the com object, opens a qb connection, starts a qb session, sends a qb request, ends a qb session, closes the qb connection.

This works fine, except that unlike the plug-in, I cannot send multiple requests from my application in one open session with QuickBooks. As soon as I issue a command prompt, the PS script does this and the PS exits and the com object is lost. They still save a live instance of the qb com object and reuse it in subsequent PowerShell sessions ...

My application issues a command prompt to start PowerShell, which starts a qb session ...

(.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 ?? 

My application uses a command line call to open a PS session. Session 2 sends a request to qb ...

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

Calling the command line to open a PS 3 session with a different request ...

Calling the command line to open a PS 4 session with a different request ...

Calling the command line to open a PS 5 session and end a qb session and close a qb connection ...

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

Is there any other way to approach this with powershell?

+5
source share
1 answer

I can’t verify that this will work for QuickBooks, but it is possible for Excel and other COM objects. You should use the Marshal.GetActiveObject method:

 # 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 

Implemented question: How to connect to an existing Excel instance from PowerShell?

UPDATE # 1:

How to make Marshal.GetActiveObject available. I get the following error ... Exception calling "GetActiveObject" with "1" argument (s): "Operation not available (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"

Perhaps this means that the third-party application is not registered as an automation server. Unable to get link to executable instance. . You can try to register a file that QBXMLRP.RequestProcessor provides (it can be dll \ tlb \ ocx \ exe) with regsvr32.exe , but given my nightly knowledge of QuickBooks I cannot give you any specific instructions. Try to find the QuickBooks installation directory for files containing the RequestProcessor line.

UPDATE: # 2

While it seems like you cannot get a live instance of the QuickBooks object, this can be mitigated through interprocess communication (IPC):

  • One script should create a QuickBooks object and then wait for input
  • The interaction of all QuickBooks is through subsequent calls to another script that simply passes requests to the first script through IPC.

IPC can be done using Named Pipes, here are a few examples:

+3
source

All Articles