Setting up the COM server using Python

Python can be used to interact with AXISVM software to build models, run analyses and retrieve results. In this article, the required steps to configure the AXISVM COM server are illustrated. The illustration presented herein employs Python; however, alternative programming languages may also be used. Python v3.10 64-bit is used here. This article will use Python’s built-in integrated development environment (IDLE), but the same steps can be followed in other editors, such as Visual Studio Code or Pycharm. AXISVM X6 64-bit is used. The same steps apply to other versions with minor alternations, as shown later in the article. It is important to mention that the versions of AXISVM software and Python should be the same, either 32-bit or 64-bit. Five steps must be followed to successfully configure the AXISVM COM server as follows:

  • Installing the comtypes package.
  • Determining the AXISVM COM server Major and Minor versions.
  • Generating the interop module in Python
  • Importing the AXISVM interop module
  • Starting AXISVM through the COM server.

Installing the comtypes package #

After installing Python and the package installer pip, the comtypes package must be installed. This package will allow calling and implementing the COM server interfaces. The comtypes can be installed by executing the following command in the command prompt, as shown in the image below. Successfully installed comtypes-version will appear if the package is installed successfully. It is recommended to install comtypes version 1.1.4 minimum, as errors were experienced with lower versions. 

pip install comtypes

 

Determining the AXISVM COM server Major and Minor versions #

The major and minor versions of the COM server must be determined to be used later in creating the interop module for Python and enabling it to see the interfaces available in the AXISVM library. The following steps must be followed to find the major and minor versions:

  • Navigate to the AXISVM installation directory.
  • Locate the file Interop.AxisVM.FW4.dll.
  • Right-click and choose properties.
  • Switch to the Details tab. 

The file version contains the information where the numbers before the first dot represent the major version, and the numbers after represent the minor version. In this example, the major version is 16, and the minor version is 100, as shown in the image below.

 

 
















Generating the interop module in Python
#

In this step, a Python wrapper for the COM server library is generated to allow Python to identify the different interfaces, properties and methods available in the COM server library. The code snippet below shows the procedures to generate the interop module. First, the comtypes and comtypes.client must be imported. Then the major_version and minor_version variables must be filled with the major and minor versions obtained in the previous step. AxVM_GUID is a unique ID for the AXISVM COM server that must not be changed. The function comtypes.GUID(AxVM_GUID) will return the typeLibrary of the COM server. AX_APP_PROGID contains the name of the main interface AxisVM.AxisVMApplication. The function GetModule will generate the interop module. If successful, the generated module will be saved in the directory of comtypes package.

				
					#import comtypes and comtypes.client
import comtypes
import comtypes.client as cc
import sys
from time import sleep
# Generate interop module for AxisVM API
# IMPORTANT NOTE: 32 bit python can generate module for 32bit AxisVM and 64bit for 64 bit COM server.
# AxisVM COM version
major_version = 16
minor_version = 100
# GUID of the AxisVM type library
AxVM_GUID = "{0AA46C32-04EF-46E3-B0E4-D2DA28D0AB08}"
# Name of the main interface.
AX_APP_PROGID = 'AxisVM.AxisVMApplication'
# generate python module 
tlb_id = comtypes.GUID(AxVM_GUID) 
try:
  cc.GetModule((tlb_id, major_version, minor_version))
  print("AxisVM module file generated")
except:
  print("""AxiVM module generation error ! \nAxisVM and Python must be on same platform (32/64 bit) !""")

				
			

Importing the AXISVM interop module #

After generating the module, it must be imported into the program to use the interfaces of the AXISVM COM server. To import the module, the following code must be executed, the MajorVersion and MinorVersion must be changed with the previously obtained MajorVersion and MinorVersion. 

				
					import comtypes.gen._0AA46C32_04EF_46E3_B0E4_D2DA28D0AB08_0_MajorVersion_MinorVersion as ax
				
			

Here, the MajorVersion is 16, and the MinorVersion is 100. The code snippet below shows how the module can be imported with major and minor versions.

				
					# importing the interop module.
try:
    import comtypes.gen._0AA46C32_04EF_46E3_B0E4_D2DA28D0AB08_0_16_100 as ax
    print("AxiVM module imported!")
except:
    print("AxiVM module import error !")

				
			

Starting AXISVM through the COM server #

The CreateObject(args) is used to create an object of the main interface AxisVM.AxisVMApplication, as shown in line 5 of the code snippet below. The created object is contained in the axApp variable. After creating the object, AXISVM cannot be controlled until it is fully loaded. Therefore, a while loop is used to check if AXISVM is loaded using axApp.Loaded property of AxisVM.AxisVMApplication object, as shown in line 25 of the code snippet below. If AXISVM is not loaded, put the program to sleep for 100ms. When the AXISVM is fully loaded, it is possible to apply properties and interact with it, such as making it visible using axApp.Visible property as shown by line 12, or axApp.CloseOnLastReleased to prevent closing AXISVM after executing the program, shown by line 13. Other functions and properties can be applied to interact with AXISVM at this stage.

				
					# starting AxisVM            
def StartAxisVM(): 
    axApp = None
    try:
        axApp = cc.CreateObject('AxisVM.AxisVMApplication', comtypes.CLSCTX_ALL,None,ax.IAxisVMApplication) #create the AxisVM.AxisVMApplication
        print("AxiVM object created")
    except:
        print("error creating the object!")
        sys.exit()
    if not axApp is None:
        if WaitForAxisVM_loaded(axApp):
            axApp.Visible = ax.lbTrue # AxisVM starts hidden, so make it visible  
            axApp.CloseOnLastReleased = ax.lbFalse # Do not close AxisVM after this code
            axApp.AskCloseOnLastReleased = ax.lbTrue # Ask whether close AxisVM after this code  
            axApp.AskSaveOnLastReleased = ax.lbTrue      
            return axApp
    if axApp is None:
        print("AxisVM start error !")
        exit()

# check if AxisVM is loaded
def WaitForAxisVM_loaded(axApp):
    # wait until AxisVM is loaded
    try:
        while not(axApp.Loaded == ax.lbTrue): 
            sleep(0.1) # wait 100 ms
            print("waiting")
        return True    
    except:
        return False

StartAxisVM()

				
			

The script to run AXISVM can be downloaded here.

Further information is available in the AXISVM COM server reference guide.