Topics

How do I access another api using Ironpython and VS2017

jpahto@...
 

Hello,

I would like to talk about this topic, as there is so scarcely information about this.

As an engineer I would like to find creative solutions to all kinds of problems that I have come across. One of these is a application programming that can pass data between design softwares. The problem is that I've come to a dead-end and I have been wracking my brain with this problem.

As it stands, I can't create a connection to a design program through my own Ironpython WPF Application. I have the required API files.I know that I need to use addReference. But after this it goes sideways. How do I create an instance for my use. All I get is the description of what type the method is under a class.

These are commonly available on C# and VBA and VB.NET, but there are no solutions for Pythonic way.

Alex Earl
 

How does it go sideways? Without information on what is going wrong, it will be very hard to help you.

jpahto@...
 

I have defined the search path for Solidworks\api\redist on VS2017.

I have defined in code:
   clr.Addreference("Solidworks.Interop.sldworks")
   import Solidworks.Interop.sldworks as swApp
   swApp.SldWorks.ActivateDoc() # Activate the currently open document on Solidworks
   Title = swApp.ModelDoc2.GetTitle()  # Idea is to get the file name as string

On __init__:
   self.ent = self.FindName('ShowFileName') # Get textbox name
   self.ent.Text = Title  # Show file name as textbox text

It feels like I'm not creating an instance to access the class correctly. This feels \\\// logically correct way for me, but I do not yet understand correctly the idea behind .NET and IronPython.
If I comment all the lines and release them one by one, the WPF Application stops working after I release the ActivateDoc line.

Stéphane Lozier
 

Looking at a SolidWorks.Interop.sldworks.dll that I found on NuGet, it seems like SldWorks and ModelDoc2 are interfaces and not instances so the first argument is expected to be an instance of the interface (e.g. swApp.SldWorks.ActivateDoc(instance)). There appears to be classes which implement these interfaces (SldWorksClass and ModelDoc2Class) so maybe you could try using those?

Here's a thread about a similar problem (with a different interop assemble): https://mail.python.org/pipermail/ironpython-users/2016-January/017599.html

jpahto@...
 

I tried to look at the steps through IronPython Interactive window:

import clr
clr.AddreferenceToFile("SolidWorks.Interop.sldworks.dll")
import Solidworks.Interop.sldworks as SldWorks

After this:

type(SldWorks)
<type 'namespace#'>

dir(SldWorks)
shows the listing correctly.

Then:

from SldWorks import SldWorks
ImportError: No module named SldWorks

Stéphane Lozier
 

This is normal Python behavior:
>>> import sys as bla
>>> assert "path" in dir(bla)
>>> from bla import path
ImportError: No module named bla

jpahto@...
 

If I use:

swApp = System.Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application"))

and then:

dir(swApp), it throws:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EnvironmentError: System.Runtime.InteropServices.COMException (0x8002802B): Elementtiä ei löydy. (HRESULT-poikkeus: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))
   kohteessa System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   kohteessa Microsoft.Scripting.ComInterop.ComRuntimeHelpers.GetITypeInfoFromIDispatch(IDispatch dispatch, Boolean throwIfMissingExpectedTypeInfo)
   kohteessa Microsoft.Scripting.ComInterop.IDispatchComObject.EnsureScanDefinedMethods()
   kohteessa Microsoft.Scripting.ComInterop.IDispatchComObject.GetMemberNames(Boolean dataOnly)
   kohteessa IronPython.Runtime.Operations.PythonOps.GetAttrNames(CodeContext context, Object o)
   kohteessa IronPython.Modules.Builtin.dir(CodeContext context, Object o)
   kohteessa Microsoft.Scripting.Interpreter.FuncCallInstruction`3.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   kohteessa System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   kohteessa Microsoft.Scripting.Interpreter.FuncCallInstruction`6.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   kohteessa IronPython.Compiler.Ast.CallExpression.Invoke1Instruction.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
   kohteessa IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
   kohteessa IronPython.Hosting.PythonCommandLine.<>c__DisplayClass27_0.<RunOneInteraction>b__0()

jpahto@...
 

"SldWorks.Application" can be activated by the version number.

for SW 2012

("SldWorks.Application.20")

for SW 2013

("SldWorks.Application.21")

for SW 2014

("SldWorks.Application.22")

for SW 2015

("SldWorks.Application.23")

for SW 2016

("SldWorks.Application.24")

for SW 2017

("SldWorks.Application.25")

If I try to use this:
>>> System.Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application.24"))
<System.__ComObject object at 0x000000000000006C [System.__ComObject]>

And then:

>>> swApp = System.Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application.24"))
>>> dir(swApp)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EnvironmentError: System.Runtime.InteropServices.COMException (0x8002802B): Elementtiä ei löydy. (HRESULT-poikkeus: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))
   kohteessa System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   kohteessa Microsoft.Scripting.ComInterop.ComRuntimeHelpers.GetITypeInfoFromIDispatch(IDispatch dispatch, Boolean throwIfMissingExpectedTypeInfo)
   kohteessa Microsoft.Scripting.ComInterop.IDispatchComObject.EnsureScanDefinedMethods()
   kohteessa Microsoft.Scripting.ComInterop.IDispatchComObject.GetMemberNames(Boolean dataOnly)
   kohteessa IronPython.Runtime.Operations.PythonOps.GetAttrNames(CodeContext context, Object o)
   kohteessa IronPython.Modules.Builtin.dir(CodeContext context, Object o)
   kohteessa Microsoft.Scripting.Interpreter.FuncCallInstruction`3.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   kohteessa System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   kohteessa Microsoft.Scripting.Interpreter.FuncCallInstruction`6.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   kohteessa IronPython.Compiler.Ast.CallExpression.Invoke1Instruction.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   kohteessa Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
   kohteessa IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
   kohteessa IronPython.Hosting.PythonCommandLine.<>c__DisplayClass27_0.<RunOneInteraction>b__0()

jpahto@...
 

If I try to call an open application:

swMain = System.Activator.GetObject(clr.GetClrType(type("SldWorks.Application")) ,"SldWorks.Application.24")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: Yritetään luoda välityspalvelinta tyyppiin, jota ei ole sidottu
SystemError: Trying to create a proxt server to a type that has not been bind.

Stéphane Lozier
 

Might just be a typo when you wrote your email, but clr.GetClrType(type("SldWorks.Application")) will give you System.String so obviously that won't work. If it's just a typo then I have no idea, you could try googling the error message ("Trying to create a proxy to an unbound type." in English).

jpahto@...
 

System.Activator.GetObject requires to inputs: (Type, String)
If the String presents HKEY_CLASSES_ROOT, then how do I get the type from this.

I have tried the methods mentioned in guide:
https://ironpython.net/documentation/dotnet/dotnet.html#creating-a-com-object
But these do not seem to also work.