seanhoran / dmstudio

Python module for Datamine Studio scripting
MIT License
22 stars 16 forks source link

Invalid COM object for StudioRMPro #3

Open mathijsvdven opened 1 year ago

mathijsvdven commented 1 year ago

Hi, I'm trying to set up the dmstudio module with Studio RM Pro (v1.11.300). The COM id appears to have changed (to "Datamine.StudioRMPro.Application") so I changed this in initialize.py:

...
# no version given, will try to find a valid version
        try:
            oScript = _scriptinit("Datamine.StudioRMPro.Application")
        except:
            try:
...

However, this results in an AssertionError on import: AssertionError: No valid Studio version is active

I tried investigating the problem by running the underlying win32com.client.Dispatch command, which returns the following error:

----> 1 client.Dispatch("Datamine.StudioRMPro.Application")

File ~\anaconda3\envs\dmstudio\lib\site-packages\win32com\client\__init__.py:117, in Dispatch(dispatch, userName, resultCLSID, typeinfo, UnicodeToString, clsctx)
    115 """Creates a Dispatch based COM object."""
    116 assert UnicodeToString is None, "this is deprecated and will go away"
--> 117 dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch, userName, clsctx)
    118 return __WrapDispatch(dispatch, userName, resultCLSID, typeinfo, clsctx=clsctx)

File ~\anaconda3\envs\dmstudio\lib\site-packages\win32com\client\dynamic.py:106, in _GetGoodDispatchAndUserName(IDispatch, userName, clsctx)
    103     ## ??? else userName remains None ???
    104 else:
    105     userName = str(userName)
--> 106 return (_GetGoodDispatch(IDispatch, clsctx), userName)

File ~\anaconda3\envs\dmstudio\lib\site-packages\win32com\client\dynamic.py:88, in _GetGoodDispatch(IDispatch, clsctx)
     86         IDispatch = pythoncom.connect(IDispatch)
     87     except pythoncom.ole_error:
---> 88         IDispatch = pythoncom.CoCreateInstance(
     89             IDispatch, None, clsctx, pythoncom.IID_IDispatch
     90         )
     91 else:
     92     # may already be a wrapped class.
     93     IDispatch = getattr(IDispatch, "_oleobj_", IDispatch)

com_error: (-2147024773, 'The filename, directory name, or volume label syntax is incorrect.', None, None)

Has anyone tried using the package with StudioRMPro and found a solution to this? Could it be related to the fact that RMPro is 64 bit?

Cheers

seanhoran commented 1 year ago

@mathijsvdven Have you contacted your local helpdesk to find out what the correct COM object for StudioRM Pro is? I don't have the version so can't test it on my side. Let me know if you figure it out!

mathijsvdven commented 1 year ago

@seanhoran I contacted APAC support but they were not much help and referred me back to this page when I asked about the Python API... Through recording a JScript from the GUI I found out that JScript calls a COM object called "StudioCommon.ScriptHelper" to create an ActiveX object. e.g.:

var oDmApp= null;
var oScript = null;
function AutoConnect()
{
   try {
      oScript = new ActiveXObject("StudioCommon.ScriptHelper");
      oScript.initialize(window);
      oDmApp = oScript.getApplication();
      if (oDmApp == null || oDmApp.ActiveProject == null)    //Attempt to Use the Active Datamine Session
      {
         alert("There are no active projects open.\n Please open a project before continuing.");
         window.close();                                                     // Closes the script window
     return false;
      }
      else
      {
         document.getElementById("logo").src = oDmApp.Options.HtmlFolder + "\\images\\Datamine_rgb_small.png";
     return true;
      }
   } 
   catch(e) {
      alert("Failed\nReason: " + e.description);
      if ( oDmApp) oDmApp.Quit(); // release the session to close it down
   }    
   return false;        
}
function btnExecute_onclick()

I have not worked with previous versions of studio so I'm not sure if this is the 'new' way to call the API for any programming language or if this has always been the JScript API. I'm pretty new to COM or ActiveX programming so was hoping someone here had bumped into the same problem. I can connect to StudioCommon.ScriptHelper using win32com.client.Dispatch and I tried basically following the same calls that JScript calls from CMD but that returns an error:

In [3]: import win32com.client as client
In [4]: c = client.Dispatch("StudioCommon.ScriptHelper")
In [5]: c.initialize("Window")
In [6]: c.getApplication()

image

seanhoran commented 1 year ago

@mathijsvdven Yeah the scripthelper is a routine in itself to initialize the underlying COM object. Its not going to work. Some other datamine users helped me define the COM objects - have no idea where they found it.

mathijsvdven commented 1 year ago

@seanhoran Right, I thought as much. Running the makepy.py script from the win32com package provides a list of COM objects with Type Libraries. image I tried a couple of those . "Datamine Studio RM 2.0 Type Library (1.0)" looks promising but fails to create a static proxy:

(dmstudio) ...\>python "...\envs\dmstudio\Lib\site-packages\win32com\client\makepy.py"
Generating to ...\AppData\Local\Temp\gen_py\3.10\28B3671B-894B-48F5-A773-ED04F71E75FEx0x1x0.py
Building definitions from type library...
Traceback (most recent call last):
  File "...\envs\dmstudio\Lib\site-packages\win32com\client\makepy.py", line 452, in <module>
    rc = main()
  File "...\envs\dmstudio\Lib\site-packages\win32com\client\makepy.py", line 439, in main
    GenerateFromTypeLibSpec(
  File "...\envs\dmstudio\Lib\site-packages\win32com\client\makepy.py", line 326, in GenerateFromTypeLibSpec
    gen.generate(fileUse, bForDemand)
  File "...\envs\dmstudio\lib\site-packages\win32com\client\genpy.py", line 1090, in generate
    self.do_generate()
  File "...\envs\dmstudio\lib\site-packages\win32com\client\genpy.py", line 1165, in do_generate
    oleItems, enumItems, recordItems, vtableItems = self.BuildOleItemsFromType()
  File "...\envs\dmstudio\lib\site-packages\win32com\client\genpy.py", line 1006, in BuildOleItemsFromType
    for type_info_tuple in self.CollectOleItemInfosFromType():
  File "...\envs\dmstudio\lib\site-packages\win32com\client\genpy.py", line 908, in CollectOleItemInfosFromType
    attr = info.GetTypeAttr()
pywintypes.com_error: (-2147312566, 'Error loading type library/DLL.', None, None)
mathijsvdven commented 1 year ago

Following up on this, I heard back from Datamine and it turns out there was an issue with the COM registration for RM Pro. They have sent me a registry fix that enables COM integration for Pro. This bug should be remedied in future releases. The fix depends on your Studio installation path so for anyone running into the issue prior to the next release, it is best to contact Support. I'll make a pull request that includes the RMPro ProgID in the initialize module.