2015-04-19 8 views
5

Ho un'app di terze parti che fino ad ora ha parlato ai quickbook utilizzando un plug-in. Quel plug-in non funziona più con le ultime versioni del sistema operativo Windows, quindi lo sto sostituendo usando gli script di PowerShell. Il plug-in instanstiates l'oggetto com QBXMLRP.RequestProcessor, quindi apre una connessione e inizia una sessione con QuickBooks, elabora varie richieste dalla mia app, quindi chiude e disconnette la connessione con i quickbook. Mentre la connessione è aperta, un ticket fornito da QuickBooks viene utilizzato per elaborare un numero qualsiasi di richieste dalla mia app.È possibile passare un'istanza dal vivo di un oggetto com tra le sessioni di PowerShell

Utilizzando PowerShell, eseguo un prompt della riga di comando per "avviare" PowerShell con un file di script .ps1 PowerShell da eseguire. Come ha fatto il plug-in, lo script PS istanzia l'oggetto com, apre una connessione qb, inizia una sessione qb, invia una richiesta qb, termina la sessione qb, chiude la connessione qb.

Funziona bene, tranne che a differenza del plug-in non posso inviare più richieste dalla mia app durante una singola sessione aperta con QuickBooks. Una volta che faccio il prompt della riga di comando, lo script PS fa la cosa e PS si chiude e l'oggetto com viene perso. È il loro comunque di preservare l'istanza diretta dell'oggetto com QB e riutilizzarla in sessioni successive PowerShell ...

mia app emette un prompt dei comandi per eseguire PowerShell che inizia una sessione qb ...

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

mia app issuse una chiamata da linea di comando per aprire PS sessione 2 inviare una richiesta al qb ...

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

chiamata da linea di comando per aprire PS sessione 3 con un'altra richiesta di ...

Comando linea di chiamata per aprire PS Sessione 4 con un'altra richiesta di ...

chiamata da linea di comando per aprire PS Sessione 5 e terminare la sessione di QB e chiudere la connessione qb ...

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

C'è un altro modo di avvicinarsi a questo utilizzando PowerShell?

risposta

3

Non riesco a verificare che funzioni per QuickBooks, ma è possibile per Excel e altri oggetti COM. Devi usare Marshal.GetActiveObject metodo:

# 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 

Realated domanda: How to connect to existing instance of Excel from PowerShell?

UPDATE # 1:

Come faccio Marshal.GetActiveObject disponibili. Sto ottenendo il seguente errore ... Eccezione chiama "GetActiveObject" con argomento "1" (s): "Operazione non disponibile (eccezione da HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"

Probabilmente ciò significa che the 3rd party app is not registered as an automation server. It is not possible to get a reference to the running instance.. Si potrebbe provare a registrare il file che espone QBXMLRP.RequestProcessor (potrebbe essere dll \ tlb \ ocx \ exe) con regsvr32.exe, ma data la mia conoscenza zero di QuickBooks non posso darti alcuna istruzione concreta. Prova a cercare la directory di installazione di QuickBooks per i file contenenti la stringa RequestProcessor.

UPDATE: # 2

Mentre sembra che non si può ottenere un'istanza diretta dell'oggetto QuickBooks, questo potrebbe essere mitigato attraverso la comunicazione tra processi (IPC):

  1. Una sceneggiatura dovrebbe creare un oggetto QuickBooks e quindi attendere l'input
  2. Tutte le interazioni QuickBooks avvengono tramite chiamate successive a un altro script, che passerà semplicemente le richieste al primo script tramite IPC.

IPC potrebbe essere fatto tramite named pipe, ecco alcuni esempi:

+0

Come faccio Marshal.GetActiveObject disponibili. Sto ottenendo il seguente errore ... Eccezione chiamata "GetActiveObject" con argomento "1": "Operazione non disponibile (Eccezione da HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))" – user278859

+0

@ user278859 Vedere l'aggiornamento, non so se aiuta, ma è il meglio che posso fare. – beatcracker

+0

Grazie per il vostro aiuto in merito. Penso che sia ora di andare avanti e accettare semplicemente che dovrò aprire e chiudere la connessione per ogni query. Funzionerà, è solo che può sembrare un po 'lento se ho richieste multiple da fare. Mi chiedo che cosa dovrei fare con questa domanda. Contrassegnare come risposta, levare senza risposta o eliminarlo? – user278859