ETABS 19 Import comtypes.client issue

Hi Everyone,

I am new to this (only experience using VBA, random C# and python scripts). I am in the process of linking dynamo with another software’s API. One of the example python scripts in the other software’s API includes this import:

import comtypes.client

Whenever I run my python script (within dynamo) I am getting an error; “ImportError: No module named comtypes.client”. I have the comtypes module installed. I understand that dynamo utilizes IronPython so it might be related to this.

Is there any workaround to make this work? I have already searched the forums and the only suggestions I found were to append these lines, to get access to

sys.path.append(“C:\Program Files (x86)\IronPython 2.7\Lib”)
sys.path.append(“C:\Program Files (x86)\IronPython 2.7\DLLs”)

The above lines fix other issues such as import os, import sys etc.I know that creating a python script that calls the other software is possible as there are a couple of custom nodes that do this already.

Appreciate the help!

Edit: If it matters I am running Revit 2018.2 and using the built-in dynamo (Dynamo Core 2.0.3.8810 and Dynamo Revit 2.0.3.8811)

Hello @moustafa.el-sawy and welcome
I don’t know which software you want to communicate with but you don’t necessarily need this module, IronPython supports accessing OleAutomation objects (COM objects )
https://ironpython.net/documentation/dotnet/dotnet.html#oleautomation-and-com-interop

Thank you :).

I am trying to communicate with ETABS (Structural software).

I will post a part of the “Example” they provide to run the software below. If I cant import comtypes.client how would I modify the code below to make it work?

import os
import sys
import comtypes.client

#set the following flag to True to attach to an existing instance of the program
#otherwise a new instance of the program will be started
AttachToInstance = False

#set the following flag to True to manually specify the path to ETABS.exe
#this allows for a connection to a version of ETABS other than the latest installation
#otherwise the latest installed version of ETABS will be launched
SpecifyPath = False

#if the above flag is set to True, specify the path to ETABS below
ProgramPath = "C:\Program Files (x86)\Computers and Structures\ETABS 17\ETABS.exe"

#full path to the model
#set it to the desired path of your model
APIPath = 'C:\CSi_ETABS_API_Example'
if not os.path.exists(APIPath):
    try:
        os.makedirs(APIPath)
    except OSError:
        pass
ModelPath = APIPath + os.sep + 'API_1-001.edb'

if AttachToInstance:
    #attach to a running instance of ETABS
    try:
        #get the active ETABS object
        myETABSObject = comtypes.client.GetActiveObject("CSI.ETABS.API.ETABSObject") 
    except (OSError, comtypes.COMError):
        print("No running instance of the program found or failed to attach.")
        sys.exit(-1)

else:
    #create API helper object
    helper = comtypes.client.CreateObject('ETABSv17.Helper')
    helper = helper.QueryInterface(comtypes.gen.ETABSv17.cHelper)
    if SpecifyPath:
        try:
            #'create an instance of the ETABS object from the specified path
            myETABSObject = helper.CreateObject(ProgramPath)
        except (OSError, comtypes.COMError):
            print("Cannot start a new instance of the program from " + ProgramPath)
            sys.exit(-1)
    else:

        try: 
            #create an instance of the ETABS object from the latest installed ETABS
            myETABSObject = helper.CreateObjectProgID("CSI.ETABS.API.ETABSObject") 
        except (OSError, comtypes.COMError):
            print("Cannot start a new instance of the program.")
            sys.exit(-1)

    #start ETABS application
    myETABSObject.ApplicationStart()

Decided to go with zerotouchnodes using C# instead. Thanks all.

1 Like

Hello,yes I think this is a good alternative
although comtypes is a pure Python package, but because comtypes has dependencies on the ctypes library which is present in Ironpython there is little chance that it will work
Regarding Marshal, the GetActiveObject method returns a proxy types which is not directly usable with IronPython (System.MarshalByRefObject instances do not support reflection)

2 Likes

I don’t know this software at all but out of curiosity I wanted to test with the ETABS API (no need Marshal).
here is a simple example with an open ETABS instance (opening Dynamo then ETABS)

import sys
import clr
import System
sys.path.append(r'C:\Program Files\Computers and Structures\ETABS 19')
assemblies = System.AppDomain.CurrentDomain.GetAssemblies()
clr.AddReferenceByName("ETABSv1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=453d728ef24c6f5e")
import ETABSv1

myHelper =  ETABSv1.Helper()
myETABSObject = myHelper.GetObject("CSI.ETABS.API.ETABSObject")
mySapModel = myETABSObject.SapModel 
#OR by Unbound Python Descriptors
#ETABSv1.cOAPI.SapModel.__get__(myETABSObject)
ret = mySapModel.File.NewSteelDeck(4, 12, 12, 4, 4, 24, 24)
OUT = mySapModel

test with Dynamo DynamoSandbox2.10 and trial version ETABS 19

6 Likes

thanks alot! Ive learned alot from that. I migrated to zerotouchnode now. Mind looking at my latest post for an issue ive been unable to solve?

Again thanks for going the extra mile of installing a trial of the software to help. I truly appreciate it.

@moustafa.el-sawy
I could not help you, I do not have any experience in zerotouchnode

1 Like

When I directly replicate the code I have following error:

module ‘clr’ has no attribute ‘AddReferenceByName’

then I have replaced the line clr.AddReferenceByName(“ETABSv1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=453d728ef24c6f5e”) with clr.AddReference(“ETABSv1”) only

then I get error as ‘wOAPI’ object has no attribute ‘SapModel’

Hi,
probably because you use the CPython3 engine.

Some solutions to test

  • try to replace clr.AddReferenceByName by clr.AddReference
  • Use IronPython2 engine (install via Package Manager)
1 Like