Sheet Set Manager API Basics

Sheet Set Manager API Basics

john_stimacH3EQQ
Enthusiast Enthusiast
1,252 Views
6 Replies
Message 1 of 7

Sheet Set Manager API Basics

john_stimacH3EQQ
Enthusiast
Enthusiast

Hello,

I'm new to this stuff, but after spending hours researching and troubleshooting I am still banging my head against the wall trying to get some pretty simple Sheet Set Manager API code to run correctly. Here are some of details of my setup:
- AutoCAD 2024 Full License

- Visual Studio 2022

- Windows 10

These are steps I took:

Project Setup

- Create a new Class Library (.NET Framework) project in Visual Studio
- Target .NET Framework 4.8 (compatible with AutoCAD 2024, Yes, I know this changes for 2025)
- VS -> Build -> Configuration Manager -> Platform x64
Add references from the following:
- References:
1.  AcSmComponents24.tlb From -> C:\Program Files\Common Files\Autodesk Shared
2. acmgd.dll From -> C:\Program Files\Autodesk\AutoCAD 2024
3. acdbmgd.dll From -> C:\Program Files\Autodesk\AutoCAD 2024
4. accoremgd.dll From -> C:\Program Files\Autodesk\AutoCAD 2024
- I made the repos location a trusted location in AutoCAD

 

 

 

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;

// Register the assembly
[assembly: ExtensionApplication(typeof(SheetSetManagerExample.SheetSetManagerPlugin))]
[assembly: CommandClass(typeof(SheetSetManagerExample.SheetSetManagerCommands))]

namespace SheetSetManagerExample
{
    // Main plugin class
    public class SheetSetManagerPlugin : IExtensionApplication
    {
        public void Initialize()
        {
            // Initialization code when AutoCAD loads the plugin
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nSheet Set Manager plugin loaded.\n");
        }

        public void Terminate()
        {
            // Cleanup when AutoCAD unloads the plugin
        }
    }

    // Class containing AutoCAD commands
    public class SheetSetManagerCommands
    {
        // Define AutoCAD commands using the CommandMethod attribute
        [CommandMethod("SSMOpenSheetSet")]
        public void OpenSheetSet()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            try
            {
                // Get DST file path from user
                PromptOpenFileOptions opt = new PromptOpenFileOptions("Select a Sheet Set (DST file)")
                {
                    Filter = "Sheet Set Files (*.dst)|*.dst"
                };

                PromptFileNameResult res = ed.GetFileNameForOpen(opt);
                if (res.Status != PromptStatus.OK) return;

                string dstFilePath = res.StringResult;

                // Create a SheetSetManager helper to work with the Sheet Set
                using (SheetSetManager ssm = new SheetSetManager())
                {
                    ssm.OpenSheetSet(dstFilePath);
                    ssm.DisplaySheetSetInfo();
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }

        [CommandMethod("SSMCreateSheetSet")]
        public void CreateSheetSet()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            try
            {
                // Get DST file path from user for the new sheet set
                PromptSaveFileOptions opt = new PromptSaveFileOptions("Specify location for new Sheet Set (DST file)")
                {
                    Filter = "Sheet Set Files (*.dst)|*.dst"
                };

                PromptFileNameResult res = ed.GetFileNameForSave(opt);
                if (res.Status != PromptStatus.OK) return;

                string dstFilePath = res.StringResult;

                // Create a SheetSetManager helper to work with the Sheet Set
                using (SheetSetManager ssm = new SheetSetManager())
                {
                    ssm.CreateSheetSet(dstFilePath, "New Sheet Set", "New sheet set created via API");
                    ssm.DisplaySheetSetInfo();
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }

        [CommandMethod("SSMAddSheet")]
        public void AddSheet()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            try
            {
                // Get DST file path from user
                PromptOpenFileOptions dstOpt = new PromptOpenFileOptions("Select a Sheet Set (DST file)")
                {
                    Filter = "Sheet Set Files (*.dst)|*.dst"
                };

                PromptFileNameResult dstRes = ed.GetFileNameForOpen(dstOpt);
                if (dstRes.Status != PromptStatus.OK) return;

                string dstFilePath = dstRes.StringResult;

                // Get DWG file path from user
                PromptOpenFileOptions dwgOpt = new PromptOpenFileOptions("Select a Drawing (DWG file)")
                {
                    Filter = "Drawing Files (*.dwg)|*.dwg"
                };

                PromptFileNameResult dwgRes = ed.GetFileNameForOpen(dwgOpt);
                if (dwgRes.Status != PromptStatus.OK) return;

                string dwgFilePath = dwgRes.StringResult;

                // Get the layout name
                PromptStringOptions layoutOpt = new PromptStringOptions("\nEnter layout name: ")
                {
                    AllowSpaces = true,
                    DefaultValue = "Layout1"
                };

                PromptResult layoutRes = ed.GetString(layoutOpt);
                if (layoutRes.Status != PromptStatus.OK) return;

                string layoutName = layoutRes.StringResult;

                // Create a SheetSetManager helper
                using (SheetSetManager ssm = new SheetSetManager())
                {
                    ssm.OpenSheetSet(dstFilePath);
                    ssm.AddSheet(dwgFilePath, layoutName, "Sheet " + DateTime.Now.ToString("yyyyMMdd"), "New sheet added via API");
                    ssm.DisplaySheetSetInfo();
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }

        [CommandMethod("SSMAddCustomProperty")]
        public void AddCustomProperty()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            try
            {
                // Get DST file path from user
                PromptOpenFileOptions opt = new PromptOpenFileOptions("Select a Sheet Set (DST file)")
                {
                    Filter = "Sheet Set Files (*.dst)|*.dst"
                };

                PromptFileNameResult res = ed.GetFileNameForOpen(opt);
                if (res.Status != PromptStatus.OK) return;

                string dstFilePath = res.StringResult;

                // Get property name
                PromptStringOptions propNameOpt = new PromptStringOptions("\nEnter property name: ")
                {
                    AllowSpaces = false
                };

                PromptResult propNameRes = ed.GetString(propNameOpt);
                if (propNameRes.Status != PromptStatus.OK) return;

                string propName = propNameRes.StringResult;

                // Get property value
                PromptStringOptions propValueOpt = new PromptStringOptions("\nEnter property value: ")
                {
                    AllowSpaces = true
                };

                PromptResult propValueRes = ed.GetString(propValueOpt);
                if (propValueRes.Status != PromptStatus.OK) return;

                string propValue = propValueRes.StringResult;

                // Create a SheetSetManager helper
                using (SheetSetManager ssm = new SheetSetManager())
                {
                    ssm.OpenSheetSet(dstFilePath);
                    ssm.AddCustomPropertyToSheetSet(propName, propValue);
                    ssm.DisplaySheetSetInfo();
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }

        [CommandMethod("SSMCreateSubset")]
        public void CreateSubset()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            try
            {
                // Get DST file path from user
                PromptOpenFileOptions opt = new PromptOpenFileOptions("Select a Sheet Set (DST file)")
                {
                    Filter = "Sheet Set Files (*.dst)|*.dst"
                };

                PromptFileNameResult res = ed.GetFileNameForOpen(opt);
                if (res.Status != PromptStatus.OK) return;

                string dstFilePath = res.StringResult;

                // Get subset name
                PromptStringOptions nameOpt = new PromptStringOptions("\nEnter subset name: ")
                {
                    AllowSpaces = true
                };

                PromptResult nameRes = ed.GetString(nameOpt);
                if (nameRes.Status != PromptStatus.OK) return;

                string subsetName = nameRes.StringResult;

                // Get subset description
                PromptStringOptions descOpt = new PromptStringOptions("\nEnter subset description: ")
                {
                    AllowSpaces = true
                };

                PromptResult descRes = ed.GetString(descOpt);
                if (descRes.Status != PromptStatus.OK) return;

                string subsetDesc = descRes.StringResult;

                // Create a SheetSetManager helper
                using (SheetSetManager ssm = new SheetSetManager())
                {
                    ssm.OpenSheetSet(dstFilePath);
                    ssm.CreateSubset(subsetName, subsetDesc);
                    ssm.DisplaySheetSetInfo();
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }
    }
}

 

 

 

 

No errors when I rebuild it in VS. There are these two warnings:
1. warning MSB3305: Processing COM reference "AXDBLib" from path "C:\Program Files\Common Files\Autodesk Shared\axdb24enu.tlb". Interface 'IAcadShadowDisplay' is marked as [dual], but does not derive from IDispatch. It will be converted as an IUnknown-derived interface.
2. warning MSB3305: Processing COM reference "ACSMCOMPONENTS24Lib" from path "C:\Program Files\Common Files\Autodesk Shared\AcSmComponents24.tlb". At least one of the arguments for 'IAcSmFiler.ReadRawData' cannot be marshaled by the runtime marshaler. Such arguments will therefore be passed as a pointer and may require unsafe code to manipulate.

But what I found online is saying these wont be an issue.

I can load the plugin in AutoCAD and run some of the commands. It lets me select the .dst file and will return some of it's values. I see this error a bunch: "Warning checking for open database: Error HRESULT E_FAIL has been returned from a call to a COM component." and this one too: " Object reference not set to an instance of an object."

I feel like there must be something simple I'm missing but can't be sure. Any help would be appreciated. 

0 Likes
Accepted solutions (1)
1,253 Views
6 Replies
Replies (6)
Message 2 of 7

daniel_cadext
Advisor
Advisor

you might have a look at this for guidance

https://adndevblog.typepad.com/autocad/2013/09/using-sheetset-manager-api-in-vbnet.html

 

I used it for this

http://www.theswamp.org/index.php?topic=59643.0

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
Message 3 of 7

john_stimacH3EQQ
Enthusiast
Enthusiast

Thanks this does help. But, I am still struggling with COM issues. AutoCAD keep crashing and I see this all the time in the error report: "Class not registered at ACSMCOMPONENTS24Lib". I have tried each of the following separately:
- Adding the reference -> COM -> Type Libraries -> AcSmComponents24 1.0 Type Library
- Adding the reference -> Browse -> "C:\Program Files\Autodesk\AutoCAD 2024\AcSmComponents.dll"
- Adding the reference -> Browse -> "C:\Program Files\Autodesk\AutoCAD 2024\AcSmComponents.Interop.dll"
- Adding the reference -> Browse -> "C:\Program Files\Common Files\Autodesk Shared\AcSmComponents24.tlb"

Also, when I try to register these references I get this error consistently:
regsvr32 "C:\Program Files\Autodesk\AutoCAD 2024\AcSmComponents.dll"
regsvr32 "C:\Program Files\Common Files\Autodesk Shared\AcSmComponents24.tlb"
regsvr32 "C:\Autodesk\ObjectARX_for_AutoCAD_2024_Win_64bit_dlm\inc-x64\acsmcomponents24.tlb"

"The module "C:\Program Files\#########\###########\AcSmComponents.dll" was loaded but the entry-point DIIRegisterServer was not found. Make sure that "C:\Program Files\#########\#######\AcSmComponents.dll" is a valid DLL or OCX file then try again."

There is an error in VS which seems related but my IDE is saying these wont be an issue:
"warning MSB3305: Processing COM reference "ACSMCOMPONENTS24Lib" from path "C:\Program Files\Common Files\Autodesk Shared\AcSmComponents24.tlb". At least one of the arguments for 'IAcSmFiler.ReadBytes' cannot be marshaled by the runtime marshaler. Such arguments will therefore be passed as a pointer and may require unsafe code to manipulate."

0 Likes
Message 4 of 7

john_stimacH3EQQ
Enthusiast
Enthusiast

I may have it figure out

Message 5 of 7

daniel_cadext
Advisor
Advisor

I think using regsvr32 is wrong, AutoCAD installer should do this

Also "warning MSB3305:” is not an error, it’s a warning that IAcSmFiler may require special handling.

 

Looking in my python wrappers, I import acax24ENU.tlb and acsmcomponents24.tlb

Maybe someone more familiar with .NET can chime in

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 6 of 7

ActivistInvestor
Mentor
Mentor
Accepted solution

The DLLs your project is registering do not have to be registered and shouldn't be registered again, which could corrupt the installation. AutoCAD registers those components on installation and there is no need for your app to do that.

 

AcSmComponents is not an ActiveX server (hence the MSB3305 warning). ActiveX servers and COM servers are two different things. The warning about the argument to IAcSmFiler.ReadBytes is because IAcSmFiler is not an ActiveX server, it's COM server, but your project sees them as ActiveX server.

 

To use the SheetSet API, you only need to do what I do in this screen clip (this is for AutoCAD 2025)

 

devenv_Jubs3VifRF.gif

 

 

Once you've added the COM reference, you can use the SSM components in code by adding this to your usings:

using ACSMCOMPONENTS25Lib;

 

0 Likes
Message 7 of 7

daniel_cadext
Advisor
Advisor

IAcSmAcDbDatabase can return IAcadDatabase, must be why I added a reference to acax

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes