Trying to access Quickbooks Desktop

29 views
Skip to first unread message

Neil Aggarwal

unread,
Mar 5, 2025, 3:48:32 PMMar 5
to jna-...@googlegroups.com
Hello all:

I am trying to write Java code to access data inside Quickbooks Desktop.

Looking at their tutorial:
https://developer.intuit.com/app/developer/qbdesktop/docs/develop/connecti
ons-sessions-and-authorizations

It says I need to do this in Visual Basic:
Dim MyQbXMLRP2 As QBXMLRP2Lib.RequestProcessor2
Set MyQbXMLRP2 = New QBXMLRP2Lib.RequestProcessor2

They provided a link to an article which uses JACOB to do it:
https://molecularbear.com/blog/using-the-quickbooks-sdk-via-jacob-java-com
-bridge/

It has this:
Dispatch qbsm = new Dispatch("QBFC7.QBSessionManager");

Looking at the JNA JavaDoc, I found this:
https://github.com/java-native-access/jna/blob/master/www/PlatformLibrary.
md

It says to use COMBindingBaseObject.oleMethod, but I have no idea how to
call it.
I came up with this:

public class RequestProcessor extends COMBindingBaseObject {
public RequestProcessor() {
super("QBFC7.QBSessionManager", false);
oleMethod(OleAuto.DISPATCH_METHOD, null, null);
}

But I have no idea where to go from here.

Any pointers?

Thank you,
Neil

--
Neil Aggarwal, (972) 834-1565, http://www.propfinancing.com
We offer 30 year loans on single family houses!

Matthias Bläsing

unread,
Mar 6, 2025, 3:26:49 PMMar 6
to jna-...@googlegroups.com
Hi Neil,

Am Mittwoch, dem 05.03.2025 um 14:48 -0600 schrieb Neil Aggarwal:
> It has this:
> Dispatch qbsm = new Dispatch("QBFC7.QBSessionManager");
>
> Looking at the JNA JavaDoc, I found this:
> https://github.com/java-native-access/jna/blob/master/www/PlatformLibrary.
> md
>
> It says to use COMBindingBaseObject.oleMethod, but I have no idea how to
> call it.
> I came up with this:
>
> public class RequestProcessor extends COMBindingBaseObject {
> public RequestProcessor() {
> super("QBFC7.QBSessionManager", false);
> oleMethod(OleAuto.DISPATCH_METHOD, null, null);
> }
>
> But I have no idea where to go from here.
>
> Any pointers?

Have a look at the word and excel examples in the repository:

https://github.com/java-native-access/jna/tree/master/contrib/msoffice

There are two variants demonstrated there:

- Variant 1:
https://github.com/java-native-access/jna/tree/master/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office
- Variant 2:
https://github.com/java-native-access/jna/tree/master/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office

For Variant 2 a binding generator is available here (it is published to
maven central):

https://github.com/matthiasblaesing/TlbCodeGenerator

And used to provide these:

https://github.com/matthiasblaesing/COMTypelibraries/

Experience from the past: You need to start with simple examples and
get a feeling for how it works. At my job at the time I wrote that the
code was used to do Word and Outlook automation. These are just COM
Dispatch calls.

Greetings

Matthias

Neil Aggarwal

unread,
Mar 7, 2025, 12:15:30 PMMar 7
to jna-...@googlegroups.com
> Experience from the past: You need to start with simple examples and get a
> feeling for how it works.

Agreed. I am trying to go step-by-step, but the documentation is using
examples
in other languages and different circumstances. I feel a bit like I am
fumbling around
in the dark.

Reading the docs from Intuit, I think I would like to use their XML
interface
instead of the foundation classes since it seems the XML is more functional.
Therefore, I am trying to follow their VB example and write it in Java.

Looking at the two variants you linked me to, Variant 2 seems very
complicated
so I tried looking at Variant 1 which seems approachable.

Using that and some stuff I found on the Internet, I came up with the
attached sample class file.

I have QuickBooks open on the company file I am trying to access.

It seems to be working to a point. QuickBooks prompts me to allow or deny
access to the application. When I allow it, I get this error:

Exception in thread "main"
com.sun.jna.platform.win32.COM.COMInvokeException: Exception
occurred.(HRESULT: 80020009)
Source: QBXMLRP2.RequestProcessor.2
Description: The ticket parameter is invalid.
at com.sun.jna.platform.win32.COM.COMUtils.checkRC(COMUtils.java:187)
at
com.sun.jna.platform.win32.COM.COMBindingBaseObject.oleMethod(COMBindingBaseObject.java:261)
at
com.sun.jna.platform.win32.COM.COMBindingBaseObject.oleMethod(COMBindingBaseObject.java:188)
at
com.sun.jna.platform.win32.COM.COMLateBindingObject.invoke(COMLateBindingObject.java:281)
at
com.sun.jna.platform.win32.COM.COMLateBindingObject.invoke(COMLateBindingObject.java:298)
at com.propfinancing.qb.JNATest.run(JNATest.java:28)
at com.propfinancing.qb.JNATest.main(JNATest.java:33)

It is not complaining about my simple XML, it is complaining about the
ticket which I should have
received back from the BeginSession call. I am not sure what I am supposed
to do about that.
JNATest.java

Matthias Bläsing

unread,
Mar 7, 2025, 2:53:18 PMMar 7
to jna-...@googlegroups.com
Hi Neil,


Am Freitag, dem 07.03.2025 um 11:15 -0600 schrieb Neil Aggarwal:
>
> Using that and some stuff I found on the Internet, I came up with the
> attached sample class file.
>
> I have QuickBooks open on the company file I am trying to access.
>
> It seems to be working to a point. QuickBooks prompts me to allow or deny
> access to the application. When I allow it, I get this error:
>
> Exception in thread "main"
> com.sun.jna.platform.win32.COM.COMInvokeException: Exception occurred.(HRESULT: 80020009)
> Source: QBXMLRP2.RequestProcessor.2
> Description: The ticket parameter is invalid.
> at com.sun.jna.platform.win32.COM.COMUtils.checkRC(COMUtils.java:187)
> at com.sun.jna.platform.win32.COM.COMBindingBaseObject.oleMethod(COMBindingBaseObject.java:261)
> at com.sun.jna.platform.win32.COM.COMBindingBaseObject.oleMethod(COMBindingBaseObject.java:188)
> at com.sun.jna.platform.win32.COM.COMLateBindingObject.invoke(COMLateBindingObject.java:281)
> at com.sun.jna.platform.win32.COM.COMLateBindingObject.invoke(COMLateBindingObject.java:298)
> at com.propfinancing.qb.JNATest.run(JNATest.java:28)
> at com.propfinancing.qb.JNATest.main(JNATest.java:33)

These are the call signatures for the relevant methods (using oleview
on QBXMLRP2.dll):

[id(0x0000000f), helpstring("method OpenConnection2")]
HRESULT OpenConnection2(
[in] BSTR appID,
[in] BSTR appName,
[in] QBXMLRPConnectionType connPref);

[id(0x00000004), helpstring("method BeginSession")]
HRESULT BeginSession(
[in] BSTR qbFileName,
[in] QBFileMode reqFileMode,
[out, retval] BSTR* pTicket);

[id(0x00000001), helpstring("method ProcessRequest")]
HRESULT ProcessRequest(
[in] BSTR ticket,
[in] BSTR inputRequest,
[out, retval] BSTR* outputResponse);

What I see is, that the result of BeginSession is a BSTR* and the
parameter for ProcessRequest is a BSTR. So extract the ticket string
from the result from BeginSession and create a new VARIANT from that.

I see, that you invoke CoInitializeEx from the static initializer.
Don't do that. Nothing guarantees, that initialization runs on the same
thread as `run`. If you get different threads, behaviour is undefined.

As I found the QBXMLRP2.dll in the Intuit github repository, I was able
to use the code generator. A blind experiment (can't test as I don't
own quickbook), can be found here:

https://github.com/matthiasblaesing/JNA-Demos/tree/master/quickbooks

I admit though, that the API is so small, that binding by hand is
totally realistic and maybe better as relying on a generator.

Greetings

Matthias

Neil Aggarwal

unread,
Mar 7, 2025, 6:37:50 PMMar 7
to jna-...@googlegroups.com
> extract the ticket string from the result from
> BeginSession and create a new VARIANT from that

That worked! Thank you! Now, I can start working on the XML,
which is nothing new to me.
Reply all
Reply to author
Forward
0 new messages