Robot API with Python 2.7 using comtypes

Robot API with Python 2.7 using comtypes

serag.hassouna
Advocate Advocate
1,464 Views
6 Replies
Message 1 of 7

Robot API with Python 2.7 using comtypes

serag.hassouna
Advocate
Advocate

Hello,
I'm trying to connect to the running Robot 2017 application using python 2.7 and with the comtypes package

the following code that imports the type library file robotom.tlb gets successful.

#Comtypes importing
import sys
import os
import comtypes.client
from comtypes import COMError
from comtypes.client import CreateObject, GetModule, GetActiveObject

import array
#____
def main():
    try:
        rbt_tlb_path = "C:/Program Files/Autodesk/Autodesk Robot Structural Analysis Professional 2017/System/Exe/robotom.tlb"
        GetModule(rbt_tlb_path)
        print "Type library is successfully imported"
        print "______________"
    except(OSError,COMError):
         print "Error: a step has failed."
        print "______________"

if __name__ = '__main__':
    main()

The result at the first time of running the script is

# Generating comtypes.gen._F3A37BD0_AA2D_11D2_9844_0080C86BE4DF_0_1_0
# Generating comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0
# Generating comtypes.gen.RobotOM

I then opened both of the generated modules

#directory folder is "C:/Python27/Lib/site-packages/comtypes/gen"
_F3A37BD0_AA2D_11D2_9844_0080C86BE4DF_0_1_0.py #refers directly to robotom.tlb _00020430_0000_0000_C000_000000000046_0_2_0.py #refers to C:/Windows/System32/stdole2.tlb

added the line

import comtypes.gen.RobotOM

at the end of the try statement block to import the newly generated module.

then tried these 2 ways to get the running Robot instance (at the end of the try statement block)

  1. robotapp = GetActiveObject("Robot.Application") #progid is guessed
    #couldn't find any actual one
  2. #the instantiation mentioned in the "Getting started" documentation file.
    robotapp = RobotOM.RobotApplicationClass() #found out that there's no class with that name in the generated module, what a surprise! """ However, there's RobotApplication class, but with no listed methods or properties relevant to the actual documented Object Model.
    They're somehow listed under this attribute ((IRobotApplication._methods_)), but I've
    no clue of how to connect to the running instance to take advantage of them. """

Sadly, both ways fail.

The generated python modules are attached here in the zip file, they would be helpful for better understanding of the issue.
I'll be thankful for any help and any insight.

0 Likes
1,465 Views
6 Replies
Replies (6)
Message 2 of 7

serag.hassouna
Advocate
Advocate

I've found the ProgID of the robot application executable file, of which path is

C:\Program Files\Autodesk\Autodesk Robot Structural Analysis Professional 2017\System\Exe\robot.exe

from the registry editor.

 

Its ProgID is simply "Robot.Application.1", and the version independent ProgID is "Robot.Application".

 

Invocation of CreateObject method runs without error

for instance,

robotapp = CreateObject("Robot.Application")
print robotapp print robotapp.Project #The results are
# <POINTER(IRobotApplication) ptr=0x15d2da8 at 7b75dc8> # <POINTER(IRobotProject) ptr=0x87894a8 at 380dbc8>

however, I couldn't find the application running in the background, the same as it happens with AutoCAD.

________________
P.S. the type of thrown error with GetActiveObject is

WindowsError: [Error -2147221021] Operation unavailable
0 Likes
Message 3 of 7

Anonymous
Not applicable

Have you tried using IronPython?

0 Likes
Message 4 of 7

serag.hassouna
Advocate
Advocate

Actually I seek the original python, not IronPython, I was successful in interfacing with AutoCAD smoothly with the standard python, and I'd like to continue using the packages I have installed and used before, so, IronPython isn't an option.
______________
with IronPython, there's already a solution .

0 Likes
Message 5 of 7

serag.hassouna
Advocate
Advocate

Currently, I'm trying to register a COM object of the RSA application to the running object table (ROT), but all my attempts failed till now.
I added the robotom.tlb to the list of source files in visual studio and added the following line in the beginning of the c++ file of the MFC Application Project.

#import "C:\Program Files\Autodesk\Autodesk Robot Structural Analysis Professional 2017\System\Exe\robotom.tlb" no_namespace


This is the part of the code in the MFC Application that aims to achieve that.

 


CoInitialize(NULL); IMoniker *rbtmnk; CLSID rbtclsid; IUnknown* unkptr = NULL; IRobotApplication* rbtapp = NULL; const IID IID_IRobotApplication = __uuidof(IRobotApplication); ITypeLib* rbttlb = NULL; DWORD dwrdptr = 0; DWORD regid = 0; IRunningObjectTable *rot; //fetch the pointer using GetRunningObjectTable HRESULT hr; HRESULT hr0; HRESULT hr1; HRESULT hr11; HRESULT hr12; HRESULT hr2; HRESULT hr3; hr0 = CLSIDFromProgID(OLESTR("Robot.Application.1"), &rbtclsid); //succeeds with S_OK if (SUCCEEDED(hr0)) { hr1 = LoadTypeLibEx(L"C:\\Program Files\\Autodesk\\Autodesk Robot Structural Analysis Professional 2017\\System\\Exe\\robotom.tlb",REGKIND_REGISTER,&rbttlb); //hr1 succeeds with S_OK
hr11 = CoGetClassObject(rbtclsid, CLSCTX_LOCAL_SERVER, NULL, IID_IUnknown, (void **)&unkptr);
//hr11 succeeds with S_OK hr12 = unkptr->QueryInterface(IID_IRobotApplication, (void **)&rbtapp); //throws E_NOINTERFACE error if (SUCCEEDED(hr1)) { hr2 = CreateClassMoniker(IID_IRobotApplication, &rbtmnk); if (SUCCEEDED(hr2)) { hr3 = GetRunningObjectTable(0, &rot); hr12 = BindMoniker(rbtmnk, regid, IID_IUnknown, (void **)&unkptr);
//hr12 throws HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND) : The specified module could not be found. if (SUCCEEDED(hr3)) { hr = rot->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, unkptr, rbtmnk, &dwrdptr);
// hr throws E_INVALIDARG One or more arguments are invalid. rot->Release(); } rbtmnk->Release(); //Release rbtmnk } rbttlb->Release(); unkptr->Release(); //Release unkptr } }

CoUninitialize();

__________________________________

I hope I can find the resolution to this issue here.

 

0 Likes
Message 6 of 7

serag.hassouna
Advocate
Advocate

I've modified and reduced the code, however, it still fails.

CoInitialize(NULL);

IMoniker *rbtmnk;
CLSID rbtclsid;
IRobotApplication* rbtapp = NULL;
const IID IID_IRobotApplication = __uuidof(IRobotApplication);
ITypeLib* rbttlb = NULL;
	
DWORD dwrdptr = 0;
DWORD regid = 0;

IRunningObjectTable *rot; //fetch the pointer using GetRunningObjectTable
HRESULT hr;
HRESULT hr0;
HRESULT hr1;
HRESULT hr12;
HRESULT hr2;
HRESULT hr3;

hr0 = LoadTypeLibEx(L"C:\\Program Files\\Autodesk\\Autodesk Robot Structural Analysis Professional 2017\\System\\Exe\\robotom.tlb",REGKIND_REGISTER,&rbttlb);
//succeeds with S_OK
//LoadTypeLibEx is supposed to do universal marshaling for the interfaces defined and referenced in
//the robotom.tlb type library file. if (SUCCEEDED(hr0)) { hr1 = CLSIDFromProgID(OLESTR("Robot.Application.1"), &rbtclsid); //hr1 succeeds with S_OK if (SUCCEEDED(hr1)) { hr2 = CreateClassMoniker(rbtclsid, &rbtmnk); //The program launches as a background process //hr2 succeeds with S_OK if (SUCCEEDED(hr2)) { hr3 = GetRunningObjectTable(0, &rot); hr12 = BindMoniker(rbtmnk, regid, IID_IRobotApplication, (void **)&unkptr); //hr12 throws HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND) : The specified module could not be found. //if rbtapp is defined as an IClassFactory pointer //& IID_RobotApplication is replaced by IID_IClassFactory, hr12 will succeed.
//The question is why the IRobotApplication interface, and possibly with the
//other interfaces of robotom.tlb, is not recognizable to BindMoniker. if (SUCCEEDED(hr3)) { hr = rot->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, rbtapp, rbtmnk, &dwrdptr); // hr throws E_INVALIDARG One or more arguments are invalid.
//A moniker is created, and a bounded object is also created,
//(The one defined with IClassFactory), so what's wrong?! rot->Release(); } rbtmnk->Release(); //Release rbtmnk } rbtapp->Release(); }
rbttlb->Release(); } CoUninitialize();

Am I alone in that issue?! Smiley Frustrated

0 Likes
Message 7 of 7

serag.hassouna
Advocate
Advocate

Using the Process Monitor Tool, I found that robot.exe searches for a file named rstrt.dll.config and it's not found, this file doesn't exist on the system, I guess this may be a reason for the error

HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND) : The specified module could not be found.

Any Ideas?

 

rstrtdllconfig not found.PNG

0 Likes