interop COM list all open DWG files from all running sessions

interop COM list all open DWG files from all running sessions

Anonymous
Not applicable
2,998 Views
7 Replies
Message 1 of 8

interop COM list all open DWG files from all running sessions

Anonymous
Not applicable

New custom dev needed . Must be external,  must run outside AutoCAD. How would I list all DWG files opened by the user - the user may have more than one session running . Only one version of AutoCAD will need to be supported per year.

Thx for your patience,

Kevin.

 

 

0 Likes
Accepted solutions (1)
2,999 Views
7 Replies
Replies (7)
Message 2 of 8

FRFR1426
Collaborator
Collaborator

You can query the Runtime Object Table (ROT) for that. Here, you can download an utility named RotView which show you what is currently in the table. There will be an entry for each document opened in AutoCAD.

 

The documentation of the Windows API can be found here.

 

Philippe has written a blog post which show how to enumerate the table in C# here.

Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
0 Likes
Message 3 of 8

Anonymous
Not applicable

did you get the ROT to work ? I tried using the code from the blog - did not work for me, it only displayed one of two sessions   : (

 

0 Likes
Message 4 of 8

Anonymous
Not applicable

Aha!  i have some success ... thx Max .

 

0 Likes
Message 5 of 8

Anonymous
Not applicable

this worked for me - for now ..  I just needed to list all DWG files opened in all sessions ... in the future I will need to add much more to edit DWG CAD objects ...

 

        [DllImport("ole32.dll")]
        private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);

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

        public void allopendwgfiles()
        {
            string msg1 = "...\r\n";
            if (GetRunningObjectTable(0, out IRunningObjectTable pprot) == 0)
            {
                pprot.EnumRunning(out IEnumMoniker ppenumMoniker);
                ppenumMoniker.Reset();
                var moniker = new IMoniker[1];
                while (ppenumMoniker.Next(1, moniker, IntPtr.Zero) == 0)
                {
                    CreateBindCtx(0, out IBindCtx ppbc);
                    moniker[0].GetDisplayName(ppbc, null, out string ppszDisplayName);
                    Marshal.ReleaseComObject(ppbc);
                    if (ppszDisplayName.ToLower().Contains(".dwg")) // // .DWT .DWS maybe ...
                    {
                        pprot.GetObject(moniker[0], out object ppunkObject);
                        msg1 = msg1 + ppszDisplayName + "\r\n";
                    }
                }
            }
            System.Windows.Forms.MessageBox.Show(msg1);
        }

 

 

0 Likes
Message 6 of 8

Anonymous
Not applicable

error ... unable to cast COM ... to interface type Autodesk.AutoCAD.interop.AcadApplication ...

In trying to go further ... error occurs in the cast line of the list of COM objects AcadApplication acApp = (AcadApplication)cs1 ... why? The properties of cs1 show that it is AutoCAD - what have I missed? (AutoCAD 2018 , AutoCAD.Application.22 ...

 

 

            openDWGset = new List<string>();
            List<object> CADsessionSet = new List<object>();
            if (GetRunningObjectTable(0, out IRunningObjectTable pprot) == 0)
            {
                pprot.EnumRunning(out IEnumMoniker ppenumMoniker);
                ppenumMoniker.Reset();
                var moniker = new IMoniker[1];
                while (ppenumMoniker.Next(1, moniker, IntPtr.Zero) == 0)
                {
                    CreateBindCtx(0, out IBindCtx ppbc);
                    moniker[0].GetDisplayName(ppbc, null, out string ppszDisplayName);
                    if (ppszDisplayName.ToLower().Contains(".dwg")) 
                    {
                        object ComObject;
                        pprot.GetObject(moniker[0], out ComObject);
                        if (ComObject is null)
                            continue;
                        CADsessionSet.Add(ComObject);
                    }
                    Marshal.ReleaseComObject(ppbc);
                }
            }
            foreach(object cs1 in CADsessionSet)
            {
                try
                {
                    AcadApplication acApp = (AcadApplication)cs1;
                    foreach (AcadDocument doc1 in acApp.Documents)
                    {
                        if (!openDWGset.Contains(doc1.Name))
                            openDWGset.Add(doc1.Name);
                    }
                }
                catch(System.Exception ex1) {
                    System.Windows.Forms.MessageBox.Show(ex1.Message);
                };
            }
0 Likes
Message 7 of 8

FRFR1426
Collaborator
Collaborator
Accepted solution

You need to cast cs1 to an AcadDocument, not an AcadApplication. The objects in the ROT are documents, not application.

Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
Message 8 of 8

Anonymous
Not applicable

Thx Max!!!       : )    

 

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Autodesk.AutoCAD.Interop;
namespace nsCADi
{
    public class cadinterop
    {
        [DllImport("ole32.dll")]
        private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);
        [DllImport("ole32.dll")]
        private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
        public void AllDWGbyROT(ref List<string> openDWGset)
        {
            openDWGset = new List<string>();
            List<object> COMDocSet = new List<object>();
            if (GetRunningObjectTable(0, out IRunningObjectTable pprot) == 0)
            {
                pprot.EnumRunning(out IEnumMoniker ppenumMoniker);
                ppenumMoniker.Reset();
                var moniker = new IMoniker[1];
                while (ppenumMoniker.Next(1, moniker, IntPtr.Zero) == 0)
                {
                    CreateBindCtx(0, out IBindCtx ppbc);
                    moniker[0].GetDisplayName(ppbc, null, out string ppszDisplayName);
                    if (ppszDisplayName.ToLower().Contains(".dwg")) 
                    {
                        object ComObject;
                        pprot.GetObject(moniker[0], out ComObject);
                        if (ComObject is null)
                            continue;
                        COMDocSet.Add(ComObject);
                    }
                    Marshal.ReleaseComObject(ppbc);
                }
            }
            foreach(object cd1 in COMDocSet)
            {
                try
                {
                    AcadDocument cdoc1 = (AcadDocument)cd1;
                    AcadApplication acApp = cdoc1.Application;
                    foreach (AcadDocument doc1 in acApp.Documents)
                    {
                        if (!openDWGset.Contains(doc1.FullName))
                            openDWGset.Add(doc1.FullName);
                    }
                }
                catch(System.Exception ex1) {
                };
            }
        }
    }
}
0 Likes