Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Multiple Processes to Multiple Inventor.Application objects

4 REPLIES 4
Reply
Message 1 of 5
JamieVJohnson2
819 Views, 4 Replies

Multiple Processes to Multiple Inventor.Application objects

I have introduced a new batch modification tool that runs with such a large batch it would be better to open multiple Inventor threads, and leave them open for the user, each having a threshold maximum number of files, before the next thread is created.  The machines can handle more processing than the Inventor platform, so naturally, I run multiple Inventor threads.  This is all working out fine, but cleaning things up is not so easy.

 

This tool's purpose is to start the work for the user and let them follow up adding custom changes, then close everything.  With this tool, and others like it I find a strong need to be able to capture every instance of the processes named "Inventor" and cast each one into an Inventor.Application object.  My attempt to apply a similar process written for Excel has not been productive, so I am calling on the advanced developers for help.  Here is my code so far:

 

 For Each p As Process In Process.GetProcessesByName("Inventor")
                    'Debug.Print(p.ProcessName)
                    Dim guid As New Guid("{B6B5DC40-96E3-11d2-B774-0060B0F159EF}")
                    Dim obj As Object = Nothing
                    Dim OBJID_NATIVEOM As Long = &HFFFFFFF0
                    Dim h As IntPtr = AccessibleObjectFromWindow(p.MainWindowHandle, OBJID_NATIVEOM, guid.ToByteArray, obj)
                    Dim iApp As Inventor.Application = obj.Application
Next

I can't get the AccessibleObjectFromWindow to not throw an error (Exception thrown: 'System.OverflowException'), it was imported properly like so:

 

 

    <DllImport("Oleacc.dll")>
    Private Function AccessibleObjectFromWindow(hwnd As Int32, dwObjectID As UInt32, riid As Byte(), ByRef ptr As Object) As Int32
    End Function

My best guess is I'm not fully understanding the required inputs.  With Process.GetProcessesByName, I successfully get all (4 for my test) Inventor's running.  Next I need to turn those processes into class instances of Inventor.Application, so I can work with each one.

 

 

With the Inventor Apps I create, using (invApp = Marshal.GetActiveObject("Inventor.Application")), I keep the class references.  But I need full control over all instances of Inventor on the machine to make sure nothing is duplicating (say during a crash event that leaves things running), and to inspect open documents before processing.

 

I feel there is something I'm missing, and that it should be way simpler to late bind to a process than the googlites say.  Please help.

 

Thanks,

 

jvj

jvj
4 REPLIES 4
Message 2 of 5

Hi,

Unfortunately, Inventor or the API was not designed to support this scenario. And AccessibleObjectFromWindow is also out of the scope of Inventor API. Sorry for not being helpful.
Message 3 of 5
Owner2229
in reply to: JamieVJohnson2

Hi, look what I've found:

Aaccess-a-specific-inventorapplication-object.html

 

It's C#, but you can convert it e.g. here:

http://converter.telerik.com

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
Message 4 of 5
xiaodong_liang
in reply to: Owner2229

Hi Mike,

 

Although I have not given it a try, but it looks promising! Thank you for pointing out. I did not know my colleague just wrote out such article a few days ago.

Message 5 of 5

AccessibleObjectFromWindow out of scope means? 

 

The developers didn't create in the Inventor API com component the logic required to make this work at all? 

OR

The API help team doesn't support with this level of coding (com level that requires dll imports) because they are not paid to do so?

 

In short am I wasting my time attempting to convert this specific window handle (IntPtr) into the app object, because I am so close to solving this?

 

268620	  Afx:00007FF789EB0000:8:0000000000010005:0000000000000000:0000000000080CE7

268620	Inventor.Application.MainFrameHWND

 

  Private Declare Function AccessibleObjectFromWindow Lib "oleacc" (ByVal Hwnd As Int32, ByVal dwId As Int32, ByRef riid As Guid, <MarshalAs(UnmanagedType.IUnknown)> ByRef ppvObject As Object) As Int32
    Dim FoundWindows As List(Of IntPtr)

    Private Declare Function GetDesktopWindow Lib "user32" () As Integer
    Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
    Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Int32) As Int32
    Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer
    Private Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As IntPtr) As Int32
    Private Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean

    Private Const OBJID_NATIVEOM = &HFFFFFFF0
    Private Const OBJID_CLIENT = &HFFFFFFFC
Private Sub ListDebug()

        'calling code 
        FoundWindows = New List(Of IntPtr)
        Dim WindowHandle As IntPtr = GetDesktopWindow()
        EnumChildWindows(WindowHandle, AddressOf ListInventorChildWindows, 0)
        Dim guid As New Guid("{B6B5DC40-96E3-11d2-B774-0060B0F159EF}")

        Dim InventorApplication As Inventor.Application
        Dim InvObject As Object = Nothing
        For i As Integer = 0 To FoundWindows.Count - 1
            AccessibleObjectFromWindow(FoundWindows(i), OBJID_CLIENT, guid, InvObject)
            If Not InvObject Is Nothing Then
                InventorApplication = InvObject.Application
            End If
        Next
    End Sub

    Public Function ListInventorChildWindows(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
        Dim WindowTitle As String, Ret As Integer
        Dim ClassName As String
        ClassName = Space(255)
        Ret = GetClassName(hwnd, ClassName, 255)
        ClassName = ClassName.Substring(0, Ret)
        Debug.Print("[" & hwnd.ToString & "]  " & ClassName)

        If ClassName.Contains("Afx:00007FF789EB0000:8:0000000000010005:0000000000000000:") Then
            Ret = GetWindowTextLength(hwnd)
            WindowTitle = Space(Ret)
            GetWindowText(hwnd, WindowTitle, Ret + 1)
            Debug.Print("Window Text: " & WindowTitle)
            FoundWindows.Add(hwnd)
        End If

        Return True

    End Function
jvj

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report