4

I am having a hard time figuring out what I'm doing wrong, so I thought I would ask this at SO. I am trying to automate a measurement task (Qualcomm QXDM), hence would like to access the COM interface exposed by a measurement tool. I wrote the following python code with works perfectly:

from comtypes.client import CreateObject  
QXDM = CreateObject("QXDM.Application")
IQXDM2 = QXDM.GetIQXDM2
...

Now, I'm trying to rewrite this is C# because of some specific requirements I have. Here's what I tried:

using QXDM;
QXDM2Class IQXDM = new QXDM2Class();

But when I try to run this, I get:

Retrieving the COM class factory for component with CLSID {6777AAE0-D9D2-4EA7-996B-0EECC68F97D8} failed due to the following error: 80040154.

What am I doing wrong? I can see all the methods and interfaces provided by QXDM in the object browser in Visual Studio.

Edit: Seems like late binding is the only way to do this as Hans suggested. I modified the code to the following:

Type QXDM = Type.GetTypeFromProgID("QXDM.Application");
Object QXDMObject = Activator.CreateInstance(QXDM);

This works. The only trouble is that I need to know what methods and classes are exposed by QXDM, which I think I could figure out using the object browser. Thanks all!

Andy
  • 245
  • 5
  • 18

5 Answers5

2

Your code just isn't the same. In the Python code you are clearly using the common "Application" object. In many automation object models, that's the object from which you create other ones. Like IQXDM2 from the GetIQXDM2() method.

Your C# code seems to be trying to create the class that implements IQXDM2 directly. Cannot work, you have to go through the Application interface. It's just like the error message says, there's no "class factory" for that object, the Application interface creates it. Whatever it is called, it is almost always has "application" in the name. Use Object Browser on the interop reference to have a look-see. Look for the one that has the GetIQXDM2 method.

If you don't see anything resembling it then you may have added the wrong DLL. Look in the registry for the name of the right one. Start Regedit.exe and look at HKCR\QXDM.Application. You'll find a CLSID key with a guid. Then look at HKCR\Clsid\{guid} where {guid} is the guid you found. The InprocServer32 key has the DLL name. An out-of-process server uses the LocalServer32 key.

If that doesn't pan out then maybe the COM server was only meant to be used by scripting languages. Very unusual but it can happen. In which case you'll have to use it late-bound in your C# code. That's only easy to do with the C# 4.0 dynamic keyword or VB.NET

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hans, thanks for your response. In the object browser, I can see only the following: Interop.QXDM -> QXDM -> QXDM2Class. There is no GetQXDM2. – Andy Jan 13 '11 at 09:10
  • Hans, thanks a million for the hints. I went through the registry. The LocalServer32 has only one entry with name default, and it is "C:\PROGRA~1\Qualcomm\QXDM\Bin\QXDM.exe". – Andy Jan 14 '11 at 05:04
1

It could be the fact that the DLL are dependent on other DLL's.. Debug with ProcExp (http://www.sysinternals.com/) might give some light

StefanE
  • 7,578
  • 10
  • 48
  • 75
  • StefanE, thanks for the response, I will try ProcExp. But if there was dependency issues, wouldn't the Python code also fail? – Andy Jan 12 '11 at 17:30
1

I think the COM objects are registered OK, or your Python code would fail and you would not see them on the machine. If this is the this case, your problem is accessing the COM objects from C#. Try the approach specified here.

If the library is already registered, you can perform the following steps to have Visual Studio generate an interop assembly for you

Community
  • 1
  • 1
Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • Steve, thanks for the response. I will try the approach you pointed out, and update the results soon. – Andy Jan 12 '11 at 17:30
  • The way I added the reference was using the steps explained in the post you mentioned. Intellisense does give me the classes and methods. – Andy Jan 13 '11 at 09:10
0

HRESULT 0x80040154 means that the COM class is not registered. Try running regsvr32 on the COM dll.

codekaizen
  • 26,990
  • 7
  • 84
  • 140
  • It found the guid though, so it's in HKEY_CLASSES_ROOT. It may be a version problem or a platform target issue. – SRM Jan 12 '11 at 17:19
  • As SRM said, I can see the CLSID mentioned in the error in registry. – Andy Jan 12 '11 at 17:29
  • @SRM: The GUID in this case comes from the code generated by running Tlbimp on the typelib. That specifies the GUID and the resulting .Net class is decorated with the GUID as an attribute. – codekaizen Jan 12 '11 at 17:38
  • That depends on how he referenced the COM dll. If he referenced it from the Add Reference using the COM tab then VS will create the RCW "under the wraps". That might actually be the OP's problem. Perhaps there are multiple versions of that dll registered and he's grabbing the wrong one? That's just conjecture because it can't find the dll entry point (hence the 80040154 error code). – SRM Jan 12 '11 at 17:55
  • SRM, I used the "Add Reference" in VS and clicked on the COM tab and selected this particular object. – Andy Jan 13 '11 at 09:12
0

It could be that you are building for 64 bit. Check your platform target. Make sure it's 32 bit.

SRM
  • 1,377
  • 1
  • 10
  • 17