BlogAutomation Workshop

SolidWorks Add-in Development: Writing a Plugin in C#/.NET

SolidWorks add-in development in C#: the ISwAddin lifecycle, COM registration, CommandManager and TaskPane, event traps, and 8 mistakes that surface later.

  • 15 min read
In This Article

The hard part of writing a SolidWorks add-in is not the API calls. The hard part is that your code no longer owns its own lifetime: the add-in opens with SolidWorks, stays in memory for the whole session, listens for events, and has to withdraw cleanly when SolidWorks closes. Three things you never think about in a macro — registration, lifecycle and object ownership — meet you on day one with an add-in.

This article does not argue "macro or add-in"; that decision is taken as made. What follows is the answer to how: how the add-in is introduced to SolidWorks, where its interface is built, how it hooks into events, and which mistakes surface in the field three weeks later.

If you are still making the decision itself, I would suggest going back to the article where I go into the relationship between macros, the API and add-ins. Testing the COM connection first with SolidWorks automation in Python to validate the idea quickly is also useful — a step that comes before the add-in decision.

Ana uygulamaya eklenti bağlanmasını temsil eden illüstrasyon
Add-in layers: COM registration, lifecycle, interface, events and business logic
01 / 11

What is an add-in, and where is the architectural difference?

An add-in is a .NET class library (.dll) that runs inside the SolidWorks process. A macro is called as an external file and ends; a standalone application drives SolidWorks from outside and lives in its own window. An add-in is not between the two but somewhere else entirely: SolidWorks loads it at startup, lets it settle into its interface, and keeps it in memory until it closes. This is not a difference in capability but in lifetime and ownership — I covered which symptoms make this move necessary, in table form, in the macro versus add-in comparison.

02 / 11

ISwAddin: the two ends of the lifecycle

For a class to be recognised by SolidWorks as an add-in it must implement the ISwAddin interface. That interface has two members, and the add-in's whole story happens between them:

  • `ConnectToSW` — called when SolidWorks loads the add-in. You are handed the application object and a cookie (the add-in's identity). Menus, tabs and event subscriptions are set up here.
  • `DisconnectFromSW` — called when SolidWorks closes or the user disables the add-in. Everything set up in ConnectToSW is undone here: command groups removed, event subscriptions detached, held references released.

At connection time you do three things in order. First you store the application object SolidWorks handed you and the cookie value — the cookie is your add-in's identity and is required for button callbacks to reach you. Then you register yourself as the callback target using that cookie; skip this step and your buttons appear but nothing happens when clicked — one of the silent failures that costs the most time in the field.

Then you build the command interface: the CommandManager tab and its buttons. Last, you attach event subscriptions.

And the return value of this function matters: a successful connection must return a positive result. Return a negative one and SolidWorks does not load the add-in at all — and does not tell the user so clearly.

Two details get skipped often. First, returning false from ConnectToSW silently leaves the add-in unloaded; swallow the error and the user just says "the tab didn't appear." Second, if you do not store the cookie, button callbacks never reach you.

03 / 11

COM registration: how is the add-in introduced to SolidWorks?

The SolidWorks API is COM-based; even though your add-in is written in .NET, SolidWorks sees it as a COM component. So putting the compiled .dll in a folder is not enough — two separate registrations are required:

1. COM registration. The class is marked ComVisible and given a fixed Guid. Registration is done with the regasm tool that ships with the .NET Framework; if you are not putting the assembly in the GAC you need the /codebase switch, because SolidWorks has to know where to find the DLL on disk.

2. SolidWorks registration. SolidWorks keeps the add-ins it will load in its own registry branch. The application-level add-in list lives under HKEY_LOCAL_MACHINE, while whether the user left that add-in on or off is stored under HKEY_CURRENT_USER. In practice that distinction means: installing the add-in does not guarantee it comes up enabled for the user. Key names and exact paths can change between SolidWorks versions; confirm from the official documentation for your target version before writing your installer script.

Rather than doing this second step by hand, the common approach is to leave it to methods marked with ComRegisterFunction and ComUnregisterFunction: when regasm runs, these methods are triggered and code writes the registry entries. Installation and removal are then managed from one place.

Writing to HKEY_LOCAL_MACHINE requires administrator rights. That comes back in the deployment section.

04 / 11

The interface layer: which one, when?

An add-in's visible face rests on three main components. The choice is not aesthetic but based on how long the interaction lasts.

ComponentWhenTypical use
CommandManager tabThe user will trigger an actionBulk export, running checks, tool buttons
TaskPaneInformation must stay open for the sessionProject tree, search panel, PDM/ERP connection status
PropertyManagerPageSelection and parameters will be takenParametric generation form, property editing, step-by-step wizard

CommandManager is the add-in's identity. You add your own tab and button group, binding each button to a callback method and optionally an "is enabled" method. The second one matters: a drawing button should look greyed out when the active document is not a drawing. This small detail decides whether the user trusts the add-in.

TaskPane is a view that lives in the SolidWorks right-hand panel. You place your own WinForms/WPF control inside it. It suits showing state, not starting a job.

PropertyManagerPage is the left panel SolidWorks' own commands use. Using it instead of opening your own dialog has two advantages: the user already knows this interaction style, and it naturally allows selection from the model (face, edge, component). The handler interface that creates the page and receives its events has several version-numbered variants; pick which one to implement from the API documentation for your target SolidWorks version.

A practical order: first a single button with CommandManager, then PropertyManagerPage as the job grows, and TaskPane only if something genuinely needs to stay visible. Starting in the reverse order produces interface nobody uses.

05 / 11

Event handling and the most expensive mistake

The real capability that separates an add-in from a macro is event handling: checking when a document opens, validating before saving, updating the interface when the active document changes.

Events arrive at two levels. Application-level events come from the SldWorks object — a document opening, the active document changing. Document-level events come from interfaces specific to the document type: parts, assemblies and drawings each have their own event sets. So if you want "validate before saving" behaviour for all three document types, you have three separate subscriptions to manage.

The most insidious trap here: when a document opens you create an event listener specific to that document — and if you hold no reference to that object anywhere else, the .NET garbage collector cleans it up after a while. Events silently stop arriving. There is no error, no message; your add-in simply becomes "sometimes it doesn't work" one day.

The fix is simple but easy to forget: hold the document handlers in a dictionary (keyed by file name) and remove the entry when the document closes. That one habit solves add-in development's hardest-to-diagnose problem from the start.

That _handlers dictionary is not decoration. This is the most common mistake with COM events: if no strong reference is held anywhere to the object that set up the subscription, the garbage collector collects it after a while and events silently stop arriving. There is no error message, no exception is thrown, the build gives no warning. The add-in works correctly for minutes, then becomes "sometimes it doesn't work."

So the rule is clear: every event handler object lives, for its whole lifetime, in a collection held by the add-in class. When a document closes, that entry is removed from the collection and the subscription detached. In DisconnectFromSW, the collection is emptied.

The second common mistake is doing long work inside an event handler. Event callbacks run in the middle of SolidWorks' own flow; starting an operation there that takes minutes locks the interface and makes the user think SolidWorks has crashed.

06 / 11

Project structure: separate API access from business logic

Add-in projects always degrade the same way: SolidWorks API calls, business rules and file writing all end up inside the button callback. It works in the first version and becomes unreadable by the third rule.

The separation is made with a simple question: does this code have to know about SolidWorks?

  • The add-in layer — ISwAddin, command registration, interface. Knows SolidWorks, knows no rules.
  • The API access layer — reading properties from a document, exporting, querying geometry. Knows SolidWorks, knows no rules.
  • The business logic layer — naming rules, validation, which output is produced when. Knows the rules, knows nothing at all about SolidWorks.

The third layer not knowing about SolidWorks is not theoretical elegance but direct testability: you can test "does this revision number match this format" in seconds, without opening SolidWorks. And most rule bugs live there.

I covered the general rationale for this separation and how to build it in modular software architecture; on the add-in side its most useful property is being able to change a rule without touching the interface.

07 / 11

Why are error handling and logging mandatory?

In a macro, error handling is optional because the person making the error and the person seeing it are the same: the macro blows up, you see it, you fix it.

With an add-in that chain breaks. Your code runs on another computer, on another SolidWorks version, on an assembly you have never seen, and the feedback that reaches you is one sentence: "it didn't work." Without logs, what remains is a guessing game.

Three rules make an adequate start:

  1. Do not let exceptions leak out of event callbacks and button callbacks. An exception crossing the COM boundary appears to the user as a meaningless error or, worse, leaves SolidWorks unstable. Every entry point is wrapped in try/catch and the caught error logged.
  2. Check return values. Many SolidWorks API methods do not throw; they return null or false. An unchecked return silently produces incomplete output — the most expensive class of automation bug, and exactly the check most often skipped in add-in code produced with AI.
  3. Write to a per-user file. The log file should live in a directory the user has write access to, and should contain the version number, SolidWorks version, document name and a timestamp.

The skeleton of a button callback should always be the same and carry three rules.

One: get the active document and check for its absence. If there is no document, say something intelligible to the user and exit.

Two: do not write the actual work inside the callback. The callback is only a trigger; business logic should sit in a separate service. That separation is the only way your add-in stays testable.

Three: wrap everything in an error handler. This is the most critical rule of add-in development: no exception should cross the COM boundary. An error leaking out of a callback can leave SolidWorks itself unstable or crash it outright. Catch the error, write it to the log, show the user a plain message — and end the flow there.

08 / 11

Deployment, versioning and compatibility

Writing the add-in is half the job; making sure the same version runs on ten people's computers is the other half.

The installer. Copying files is not enough, because COM registration and registry entries are needed and these can require administrator rights. An MSI or equivalent installer reduces installation and removal to one step. Test the uninstall scenario from the start: a leftover registry entry makes SolidWorks try to load a DLL that no longer exists at startup.

Version management. Embed the add-in's version number in the assembly and show it somewhere visible in the interface (an About button or TaskPane footer). Write it into log lines too. Not having to ask the user "which version are you on" shortens support time noticeably. Keep the Guid fixed across versions — changing it forces the user to enable the add-in by hand again.

Architecture and runtime compatibility. Because the add-in loads inside the SolidWorks process, the processor architecture must match; current SolidWorks versions are 64-bit and a 32-bit build will not load. Likewise the .NET runtime your add-in targets must be within the range SolidWorks supports. The supported .NET version varies with the SolidWorks version; confirm from the official system requirements before choosing your target.

Backward compatibility. API methods have version-numbered variants, and older names may be deprecated over time. If you need to support several SolidWorks versions, compiling against the interop assembly of the oldest version you support is a common approach — but without testing on every version, that is an assumption.

09 / 11

Common mistakes

  1. Not holding strong references to event handlers. The most insidious bug. Events work for a while, then silently stop. Symptom: "sometimes it works, sometimes it doesn't."
  2. Leaving `DisconnectFromSW` empty. Command groups are not removed, subscriptions not detached, references not released. Result: SolidWorks hangs while closing, or a process stays in the background.
  3. Exceptions crossing the COM boundary. An exception leaking out of a callback looks meaningless to the user and can leave the session unstable.
  4. Not checking return values. Calls that do not throw but return null/false silently produce incomplete output.
  5. Writing everything into the button callback. Once business logic mixes into interface code, testing becomes impossible and every rule change means touching the interface.
  6. Running long work inside an event. The interface locks up and the user thinks SolidWorks has crashed.
  7. Not recording version information. A bug report from the field is useless when you do not know which version it belongs to.
  8. Changing the `Guid` between versions. The add-in "disappears" on the user's side and has to be re-enabled.
Sürüm kontrolü ve dallanmayı temsil eden illüstrasyon
An add-in is a live product: it wants versioning, deployment and a maintenance scheme
10 / 11

Frequently Asked Questions

Which languages are SolidWorks add-ins written in? Most commonly C# and VB.NET; C++ works too. The common condition is that the component can be loaded by SolidWorks over COM.

What licence do I need to develop an add-in? The API is part of the SolidWorks licence; no separate product is purchased for add-in development. The capabilities you can reach vary with the version you use.

Why doesn't my add-in show up in the add-in list? Usually one of three reasons: COM registration was not done (regasm, with /codebase if needed), the SolidWorks registry entry is missing, or the architecture does not match (32/64-bit, or an unsupported .NET version).

Why do my events stop arriving after a while? Almost always because no strong reference is held to the event handler object; when the garbage collector takes it, the subscription silently drops. Store handlers in a collection on the add-in class.

Should I open my own dialog window or use a PropertyManagerPage? If selection will be taken from the model, or the flow should feel like a SolidWorks command, use PropertyManagerPage. For a standalone, complex, rarely-opened configuration screen, a separate window is reasonable.

Can I convert my existing VBA macro directly into a C# add-in? Most calls map one to one, but a direct conversion is usually not enough: a macro assumes a one-off flow, while an add-in wants state, a lifecycle and error handling. Use the conversion as a starting point and build the architecture from scratch.

Can one add-in support several SolidWorks versions? Usually yes — the common approach is compiling against the interop assembly of the oldest version you support. But because version-dependent behaviour differences exist, it needs testing on every target version.

11 / 11

Conclusion

What makes add-in development hard is not the breadth of the API but the fact that the add-in shares a lifetime with SolidWorks. So getting three things right from day one makes everything that follows easier:

  • Full symmetry between ConnectToSW and DisconnectFromSW
  • Strong references to event handlers, and no room for long work inside an event
  • Business logic in a separate layer that knows nothing about SolidWorks

Choose the interface component by how long the interaction lasts, log your errors, make the version visible, and package the installation. The rest is largely repeating skeleton code.

If you would like to see how this architecture grows from macro level, have a look at the SolidWorks CAD automation case study. If you would like to assess together whether your own process has reached the add-in threshold, write to me from the contact section.

Part of this guideSolidWorks Automation — Macros, API and Add-ins — A Complete GuideMacro, API, or add-in? Which layer solves which job, which language to pick, and where to start — gathered on one page.İlgili projeSolidWorks Add-in GeliştirmeKamyon/treyler dorseleri arka kapı çerçevesini otomatikleştiren SolidWorks yazılımı — VBA makrodan C# Add-in'e.

Kaynaklar

ShareLinkedIn