Multiple instances of Inventor - Standalone EXE

Multiple instances of Inventor - Standalone EXE

gopinathmY575P
Advocate Advocate
659 Views
7 Replies
Message 1 of 8

Multiple instances of Inventor - Standalone EXE

gopinathmY575P
Advocate
Advocate

Hello Community,

 

i'm working on project where it requires to select/pick the required instance of Autodesk inventor active document from the multiple instances of inventor.

 

 

Thanks in advance..

0 Likes
660 Views
7 Replies
Replies (7)
Message 2 of 8

jjstr8
Collaborator
Collaborator

Inventor instances use the same item moniker in the running object table (ROT). You can tell how may instances of Inventor are running, but the object associated with each entry in the ROT will be the first (essentially oldest) instance of Inventor. I'm not sure how to get around this. Can you describe what you're trying to achieve? There may be some alternatives.

0 Likes
Message 3 of 8

gopinathmY575P
Advocate
Advocate

Team,

 

i found a way where i can able to get the list of process related to inventor documents. from list the list, i can able to select the document and manipulate that document how i need.. 

private void LoadInventorProcesses()
{
processListBox.ItemsSource = null;
IRunningObjectTable rot;
IEnumMoniker enumMoniker;
IMoniker[] monikers = new IMoniker[1];

GetRunningObjectTable(0, out rot);
rot.EnumRunning(out enumMoniker);
enumMoniker.Reset();

IntPtr fetched = IntPtr.Zero;
while (enumMoniker.Next(1, monikers, fetched) == 0)
{
IBindCtx bindCtx;
CreateBindCtx(0, out bindCtx);

string displayName;
monikers[0].GetDisplayName(bindCtx, null, out displayName);
Console.WriteLine(displayName);
if (displayName.Contains(".iam") || displayName.Contains(".ipt") || displayName.Contains(".idw"))
{

processListBox.Items.Add(displayName);
}
}
}

private void ProcessListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedProcess = (dynamic)processListBox.SelectedItem;

processListBox.ItemsSource = null;
IRunningObjectTable rot;
IEnumMoniker enumMoniker;
IMoniker[] monikers = new IMoniker[1];

GetRunningObjectTable(0, out rot);
rot.EnumRunning(out enumMoniker);
enumMoniker.Reset();

IntPtr fetched = IntPtr.Zero;
while (enumMoniker.Next(1, monikers, fetched) == 0)
{
IBindCtx bindCtx;
CreateBindCtx(0, out bindCtx);

string displayName;
monikers[0].GetDisplayName(bindCtx, null, out displayName);

if (displayName == (dynamic)processListBox.SelectedItem )
{
object comObject;
rot.GetObject(monikers[0], out comObject);

Document oAsm = (Document)comObject;

oAsm.Save2(true);
MessageBox.Show(oAsm.DisplayName);
}
}

}

0 Likes
Message 4 of 8

jjstr8
Collaborator
Collaborator

What version of Inventor are you running? This doesn't work on 2024.3.1.

0 Likes
Message 5 of 8

gopinathmY575P
Advocate
Advocate

@jjstr8 thanks for bringing this to my notice.

 

I have both 2021 and 2024. in 2021 version I have done testing and it's working fine as per expected behaviour. whereas in 2024.3.4, it's not working.

0 Likes
Message 6 of 8

jjstr8
Collaborator
Collaborator

I no longer have a prior version installed. Based this post, Getting Inventor Object in NET Core , it looks like Inventor used to change its ROT moniker based on the active file. For whatever reason, it no longer does that in 2024. The only workaround I found was to have a helper addin register another moniker in the ROT which is unique for each Inventor session. It includes the Inventor session ID (Application.ADPSessionId) which is unique for each running Inventor instance. When you look in the ROT, filter for display names starting with "!Inventor-session-moniker:"  I've attached the VS2022 project if anyone is interested.

0 Likes
Message 7 of 8

gopinathmY575P
Advocate
Advocate
0 Likes
Message 8 of 8

jjstr8
Collaborator
Collaborator

I'm not sure what's blocking you from downloading, but here's the code only. The only reference you'll need in the project is the Inventor interop. Create a .addin file as you see fit.

using System;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using Inventor;

namespace InventorSessionMoniker
{
    [Guid("40E41513-E47B-4151-95E3-99EB653FF433"), ComVisible(true)]
    public class StandardAddInServer : ApplicationAddInServer
    {
        [DllImport("ole32.dll")]
        private static extern int CreateItemMoniker([MarshalAs(UnmanagedType.LPWStr)] string delim, [MarshalAs(UnmanagedType.LPWStr)] string item, out IMoniker moniker);

        [DllImport("ole32.dll")]
        private static extern int GetRunningObjectTable(uint reserved, out IRunningObjectTable pprot);

        internal int _sessionMonikerId;
        internal Application _inventorApplication;

        public object Automation => null;

        public void Activate(ApplicationAddInSite AddInSiteObject, bool FirstTime)
        {
            _inventorApplication = AddInSiteObject.Application;
            int hResult = GetRunningObjectTable(0, out IRunningObjectTable runningObjectTable);
            if (hResult == 0)
            {
                _ = CreateItemMoniker("!", "Inventor-session-moniker:" + _inventorApplication.ADPSessionId, out IMoniker sessionMoniker);
                _sessionMonikerId = runningObjectTable.Register(0x1, _inventorApplication, sessionMoniker);
            }
        }
        public void Deactivate()
        {
            int hResult = GetRunningObjectTable(0, out IRunningObjectTable runningObjectTable);
            if (hResult == 0)
            {
                runningObjectTable.Revoke(_sessionMonikerId);
            }
            if (_inventorApplication != null)
            {
                Marshal.ReleaseComObject(_inventorApplication);
                _inventorApplication = null;
            }
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        public void ExecuteCommand(int CommandID) { }
    }
}

 

0 Likes