0

I am wrapping a COM API Ultimately I am trying to push more code down into Generics and the inheritance pattern in the api is not helping.

I have a generic of IBase, THere are ~80 classes that represent result sets. They are very similar, but they all inherit, or rather implement, the very basic IBase.

I have tried Extension methods and I dont think that is the way to go because the com is late bound and using Reflection.PropertyInfo seemed to be a dead end.

In the generic, we have the sub types, so I think I can use InvokeMember to call the methods/properties I need.

instnc = Activator.CreateComInstanceFrom(assy, tyepname)
retClass = Type.GetTypeFromProgID(progId)

My challenge is that I can not find the progId. I have searched the registry, I have made many guesses. "Excel.Application" works, so the basic approach is solid.

THe com dll in question is the Intuit Quickbooks api. I have tried many variations of

"QBFC13Lib.ICustomerRetList"

Am I on the right track? If so, where can I find the progId? Should I try a different tack?

from oleView, i see this for ICustomerRetList

[
  odl,
  uuid(DF331154-953C-4813-BAEC-F65DDBBFEB5B),
  helpstring("ICustomerTypeRetList Interface"),
  dual,
  oleautomation
]
interface ICustomerTypeRetList : IQBBase {
    [id(0x00000004), helpstring("method GetAt")]
    HRESULT GetAt(
                    long index, 
                    [out, retval] ICustomerTypeRet** retVal);
    [id(0x00000005), propget, helpstring("property Count")]
    HRESULT Count([out, retval] long* pVal);
    [id(0x00000006), helpstring("method Append")]
    HRESULT Append([out, retval] ICustomerTypeRet** retVal);
};

some more relevant lines from the typeLib

there are 36 interface declarations. I think we have established we are not after these... we want the things that implement these

interface ICustomerMsgRetList;    
interface ICustomerMod;

there are many lines that reference types such as the line below. These are simply objects that have customer as a property (Purchase order for instance). These are all found w/in Interface declarations. Its been a while since I did C++. Is IQBBase a pointer to a pointer? Thinking outloud, dont need an answer.

HRESULT CustomerRef([out, retval] IQBBaseRef** pVal);    

So yes, there may be a factory in there somewhere. I do believe these object (ICustomerRetList implementers) are instantiable, they clearly are instantiated. But the typelib is not giving up its secrets. Going back to the original question, I don't think there is an answer unless I can get the progId. The progIds may be purposefully obfuscated. Dont know. I know I guess at them and have not been successful. The intuit support forum is no longer active to the best of my knowledge.

greg
  • 1,673
  • 1
  • 17
  • 30

1 Answers1

1

You write "THe com dll in question is the Intuit Quickbooks api". I don't quite understand because that is not the name of a DLL. If you know the DLL, you can use the Microsoft utility OleView with the name of the DLL and it will display a de-compiled type library for you where you can look at all the types including ProgIds.

Personally, I would use regedit.exe and then go to HKEY_CLASSES_ROOT\TypeLib. From there I would use the search facility to search for "Intuit" or "quickbooks" to locate the typelibrary. If you find the typelibrary, then you can use OleView to browse it.

If you don't find it, you can look at your Quickbooks installation and then find its file path. After finding the path, go to HKEY_CLASSES_ROOT in RegEdit and search for the path. You should find some keys that have the path and if they are labeled LocalServer32 or InProcServer32, that will give you the CLSID and from the CLSID you can get the ProgID

Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29
  • i posted the output for ICustomerRetList. i see a uuId and a helpstring. are either of these what I am after? – greg Apr 23 '16 at 01:28
  • 1
    Having the interface name will not help you. What you need is the name of the object that implements that interface. If you have Quickbooks on your PC, go to it's directory and look for a type library (.tlb) file. It may have one, or not. The type library may be embedded in a DLL or EXE. You can try using OleView on every DLL or EXE in the Quickbooks directory to find the type library. If it exposes automation methods, you will eventually find it. The other thing you need to do is make sure your application is 64-bits if the Quickbooks DLL is 64 bits or if 32-bits also 32-bits. – Joseph Willcoxson Apr 23 '16 at 15:49
  • when i open the OleViewer, File->Load TypeLib and point to qbfcLib13.dll... i get a tree on the left, there are enumerations, interfaces, and dispInterfaces. I do understand the difference between an interface and an object that implements an interface. However, all I have ever seen in the documentation are references to the interfaces. Im not sure how , but the class names, if there are class names, seem to be masked. Maybe im not looking in the right spot. – greg Apr 24 '16 at 20:01
  • 1
    Go to the root of type library so it lists every single type on the right. It will be in IDL format. Select it all and copy it into notepad or some editor. Then search for the keyword "coclass". Objects that implement that have that MIDL attribute will be createable via CoCreateInstance. Those are the objects that you can create from code or script. They should also list the default interfaces they support. If you look at those coclass objects, they will have an uuid. You can search for the UUID in the registry. When you find it, it should have a key that has the ProgId. – Joseph Willcoxson Apr 25 '16 at 02:58
  • there are exactly 2 objects that are listed as coclass. they are toplevel objects. i don't want to paste the whole file bc it is 32k lines. I will take a look at the 2 classes and see (QBSessionManager & QBOESessionManager) the OE most likely stands for online edition. Let me see if there is a factory or something in there that is generating the instances. Could it be that there are no public constructors, and that is why I am not seeing anything in the typelib? – greg Apr 25 '16 at 16:36
  • 1
    There are no "constructors" per se in COM. What is probably happening is that you have to use QBSessionManager to create an object that implements the interface or maybe (roughly) an object that creates an object ... that creates an object that implements your interface. Look for partial matches of ICustomerTypeList like "CustomerType" or even just Customer and try to work backwards. – Joseph Willcoxson Apr 26 '16 at 02:41
  • I really really appreciate the continued interest. I searched the entire typelib and came up w/ about 300 references to the word customer. I filtered out enumeration entries, and references to 'Helpstring' and was down to about 125. Most of these are Interface declarations. Ill post some more lines in my question. – greg Apr 29 '16 at 15:24
  • Joe - I am going to abandon this line of inquiry. You have been incredibly helpful and I have learned quite a bit about COM over the last 2 weeks. Granted, thats a bit like studying latin, but all learning is good, IMHO. I am going to close the question. The work around here is to generate some ~30 lines of code per class. Codesmith is doing that work, so I cant justify wasting any more of your time or my time on this. Thanks again. – greg Apr 29 '16 at 15:34