2015-04-19 3 views
5

Ich habe eine Drittanbieter-App, die bis jetzt mit Quickbooks über ein Plug-in gesprochen. Dieses Plug-in funktioniert nicht mehr mit den neuesten Versionen des Windows-Betriebssystems, daher ersetze ich es mit PowerShell-Skripten. Das Plug-In würde das QBXMLRP.RequestProcessor com-Objekt instanziieren, dann eine Verbindung öffnen und eine Sitzung mit QuickBooks beginnen, verschiedene Anfragen von meiner App bearbeiten, dann die Verbindung schließen und die Verbindung mit Quickbooks trennen. Während die Verbindung offen ist, wird ein von QuickBooks bereitgestelltes Ticket verwendet, um eine beliebige Anzahl von Anfragen aus meiner App zu bearbeiten.Ist es möglich, eine Live-Instanz eines com-Objekts zwischen PowerShell-Sitzungen zu übergeben

Mit PowerShell führe ich eine Befehlszeile aus, um PowerShell mit einer PowerShell .ps1-Skriptdatei zum Ausführen zu starten. Wie das Plugin getan hat, instanziiert das PS-Skript das com-Objekt, öffnet eine qb-Verbindung, beginnt eine qb-Sitzung, sendet eine qb-Anfrage, beendet die qb-Sitzung, schließt die qb-Verbindung.

Das funktioniert gut, außer dass ich im Gegensatz zu dem Plug-in nicht mehrere Anfragen von meiner App während einer einzigen offenen Sitzung mit QuickBooks senden kann. Sobald ich die Befehlszeilen-Eingabeaufforderung ausstelle, macht das PS-Skript seine Sache und PS wird beendet und das com-Objekt ist verloren. Ist sie ohnehin die Live-Instanz des qb com Objekts und wieder verwendet es in der folgenden Powershell-Sitzungen zu erhalten ...

Meine app gibt eine Eingabeaufforderung ausführen Powershell, die eine qb Sitzung beginnt ...

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

Meine app einen Kommandozeilenaufruf zu öffnen PS Session 2 Anfrage senden an qb ...

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

Kommandozeilenaufruf zu öffnen PS Session 3 mit einer anderen Anfrage issuse ...

Kommandozeilenaufruf PS Session 4 mit einer weiteren Anfrage zu öffnen ...

Kommandozeilenaufruf PS Session 5 zu öffnen und die qb-Sitzung zu beenden und die qb Verbindung schließen ...

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

Gibt es eine anderes Möglichkeit, dies mit Powershell zu nähern?

Antwort

3

Ich kann nicht überprüfen, dass dies für QuickBooks funktioniert, aber es ist für Excel und andere COM-Objekte möglich. Sie haben Marshal.GetActiveObject Methode verwenden:

# 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 Frage: How to connect to existing instance of Excel from PowerShell?

UPDATE # 1:

Wie mache ich Marshal.GetActiveObject zur Verfügung. Ich erhalte den folgenden Fehler ... Exception "GetActiveObject" mit "1" Argumente Aufruf (e): "Operation nicht zur Verfügung (Ausnahme von HRESULT: 0x800401e3 (MK_E_UNAVAILABLE))"

Wahrscheinlich bedeutet dies, dass the 3rd party app is not registered as an automation server. It is not possible to get a reference to the running instance.. Sie könnten versuchen, eine Datei zu registrieren, die QBXMLRP.RequestProcessor (es könnte dll \ tlb \ ocx \ exe sein) mit regsvr32.exe, aber angesichts meiner Null Kenntnisse von QuickBooks kann ich Ihnen keine konkreten Anweisungen geben. Versuchen Sie, das QuickBooks-Installationsverzeichnis nach Dateien mit der Zeichenfolge RequestProcessor zu durchsuchen.

UPDATE:

  1. Ein Skript: # 2

    Während es scheint, dass Sie nicht eine Live-Instanz des Objekts Quickbooks bekommen kann, könnte dies über die Interprozesskommunikation (IPC) entschärft werden sollte ein QuickBooks-Objekt erstellen und dann auf Eingabe warten

  2. Alle QuickBooks-Interaktion erfolgt über nachfolgende Aufrufe an ein anderes Skript, das nur Anforderungen an das erste Skript über IPC weitergibt.

IPC über Named Pipes getan werden könnte, ist hier einige Beispiele:

+0

Wie kann ich Marshal.GetActiveObject zur Verfügung zu stellen. Ich bekomme den folgenden Fehler ... Exception Aufruf "GetActiveObject" mit "1" Argument (e): "Operation nicht verfügbar (Ausnahme von HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))" – user278859

+0

@ user278859 Siehe Update, nicht sicher, ob es hilft, aber es ist das Beste, was ich tun kann. – beatcracker

+0

Danke für Ihre Hilfe zu diesem Thema. Ich denke, es ist Zeit, weiterzugehen und einfach zu akzeptieren, dass ich die Verbindung für jede Abfrage öffnen und schließen muss. Es wird funktionieren, es ist nur so, dass es ein wenig langsam erscheinen kann, wenn ich mehrere Anfragen machen muss. Ich frage mich, was ich mit dieser Frage tun sollte. Markieren Sie es als beantwortet, lassen Sie es unbeantwortet, oder löschen Sie es? – user278859