1

I'm trying to control a device (Gamry Interface 5000 Potentiostat) via its COM interface using win32com.

# Imports
import win32com.client as client

# Get device list
devices = client.Dispatch('GamryCOM.GamryDeviceList')

# Iterate through devices
for i in range(devices.Count()):
    # Get device (this wors as we only have one connected yet)
    device = devices.EnumSections()[i]
    print(device)
    
# Setup potentiostat object
potentiostat = client.Dispatch('GamryCOM.GamryPstat')

When I run this, I got the following error message:

IFC5000-10519
Traceback (most recent call last):
  File "c:\Users\Rob\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 86, in _GetGoodDispatch
    IDispatch = pythoncom.connect(IDispatch)
pywintypes.com_error: (-2147221021, 'Operation unavailable', None, None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\Users\[...]\gamry_control_01.py", line 23, in <module>
    potentiostat = client.Dispatch('GamryCOM.GamryPstat', clsctx = pythoncom.CLSCTX_LOCAL_SERVER )
  File "c:\Users\Rob\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\__init__.py", line 117, in Dispatch
    dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch, userName, clsctx)
  File "c:\Users\Rob\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 106, in _GetGoodDispatchAndUserName
    return (_GetGoodDispatch(IDispatch, clsctx), userName)
  File "c:\Users\Rob\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 88, in _GetGoodDispatch
    IDispatch = pythoncom.CoCreateInstance(
pywintypes.com_error: (-2147221164, 'Class not registered', None, None)

Funnily enough, the first dispatch-statement just works fine, Just the second one fails.

I'm using a 64 Bit Windows 11 setup and tested different Python environments:

  • Python 3.10 64 Bit, win32com-303 64 Bit
  • Python 3.9 32 Bit, win32com-303 32 Bit

I also tried using comtypes instead of win32com which resulted in the same error.

Thank you very much for your help!

Regards

3
  • 1
    Maybe check the class is registered, using the Registry Editor. Search HKEY_CLASSES_ROOT for the class name: and then check you have the correct spelling, I guess. As you say, odd that one class is registered and the other not. Commented Feb 6, 2022 at 17:54
  • Hey, thanks for your reply. I just checked the registry and all relevant classes in there are spelled correctly. Also, there aren't any obvious differences between the classes that work and those than aren't. Commented Feb 6, 2022 at 19:01
  • If you have the Windows SDK installed, you can use a utility called oleview.exe to explore all the objects, interfaces and type libraries that are registered on your system. NB you have to run it for the first time with elevated permissions. That has the option to attempt to create an instance of an object, as well as explore what interfaces it provides. Commented Feb 7, 2022 at 11:28

3 Answers 3

2

To add on to the 64bit VS 32bit COM objects this article was helpful https://www.codeproject.com/Tips/267554/Using-32-bit-COM-Object-from-64-bit-Application

I will list out the steps in case of internet decay

Using a 32-bit COM Object from a 64-bit Application:

  1. Locate your COM object GUID under HKey_Classes_Root/Wow6432Node/CLSID.
  2. Once located, add a new REG_SZ (string) value. The name should be AppID and the data should be the same COM object GUID you have just searched for.
  3. Add a new key under HKey_Classes_Root/Wow6432Node/AppID. The new key should be called the same as the COM object GUID.
  4. Under the new key you just added, add a new REG_SZ (string) value, and call it DllSurrogate. Leave the value empty.
  5. Create a new key under HKey_Local_Machine/Software/Classes/AppID, if it doesn't already exist. Again, the new key should be called the same as the COM object's GUID. No values are necessary to be added under this key.

Using these steps I created the necessary .reg files to automate the process in cases like switching computers etc..

Sign up to request clarification or add additional context in comments.

Comments

1

I had the same problem and contacted a Salesman. He sent me a document, saying that on some devices you have to use pstat = client.CreateObject('GamryCOM.GamryPC5Pstat') for the Reference family and pstat = client.CreateObject('GamryCOM.GamryPC6Pstat') for the Interface family. For me, at least the OSError: [WinError -2147221164] Class not registered disappears. I've used "comtypes".

Comments

1

"Class not registered" means it cannot find the class factory for the class. That's an error independent of Python and has nothing to do with it...other than the bitness of Python (whether it is 32 or 64-bit, and whether the COM server is 32 or 64-bit). It also matters whether the server is In Process (a DLL) or Out of Process (EXE). For EXE, it really doesn't matter, but for an In-Process server, the bitness of the calling program and the COM server have to match. In order to see if you have a bitness problem, do this...

Create the following VB Script, call it test.vbs

set obj = CreateObject("GamryCOM.GamryDeviceList")
MsgBox TypeName(obj)

Call the script two times from the command line, one with the 64-bit VB Script engine, and once with the 32-bit engine. If you're running from a directory other where test.vbs is located, you'll have to supply the path to test.vbs as well.

64-bit engine:

c:\windows\system32\wscript.exe test.vbs

32-bit engine:

c:\windows\syswow64\wscript.exe test.vbs

If the object is correctly registered and an EXE server, it should succeed for the script run both as 32 and 64-bit. If the object is correctly registered and a DLL server, it will succeed for only one run of the above script. If the object is incorrectly registered, it will fail for the script run with both engines.

In the case of double failure, you will have to figure out how the producer of the COM object expects you to call it. It could be licensing is involved.

In the case of single failure, you will have to use a different bitness of Python to match the server, or if you're truly running 64-bit Python as you say, then maybe figure a way to host the 32-bit DLL in 64-bits using something like DllHost. I've never done it, but there are articles online on how to do it.

1 Comment

Thanks for your detailed answer. I tested two classes (GamryCOM.GamryDeviceList and GamryCOM.GamryPstat) and for the first class, it worked for 32 bit and 64 bit. However, the second class failed for both bit-level with an "ActiveX component can't create object: 'GamryCOM.GamryPStat' Code (800A01AD)". This error may help me find the issue. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.