A SolidWorks macro gets you 80 percent of the way there. It can open files, traverse assemblies, read custom properties, save DXF, and close — all without writing a line of C#. The VBA IDE ships inside SolidWorks, the API reference is documented, and a working batch export macro can be running in an afternoon.
Then the macro breaks in a way that a one-line fix will not solve. Or someone needs it on fifteen workstations, or the team wants a toolbar button, or the workflow needs to respond to file saves without being manually invoked. That is when engineers discover that “just adding a button” requires a complete architectural shift. Macros and add-ins are not on the same continuum — they differ at the design level, and the capabilities that matter most to production workflows sit entirely on the add-in side of that line.
The architectural difference
A SolidWorks macro is a script. It runs when invoked via Tools → Macro → Run, executes top to bottom, and terminates. The SolidWorks process hosts it, but the macro has no mechanism to stay alive between invocations. It cannot receive events. It cannot hold state across runs. When execution ends, the entire context is gone.
A COM add-in is a DLL registered in the Windows registry under the SolidWorks add-in GUID. SolidWorks loads it at startup (if the “Start Up” checkbox is checked in the Add-in Manager) and calls ConnectToSW(). The add-in then lives for the entire SolidWorks session — same process, same memory space, fully in-process. It subscribes to events, holds data, and responds to user interactions without being explicitly invoked. When SolidWorks closes, the add-in receives DisconnectFromSW() and cleans up.
Both macros and add-ins call the same SolidWorks API methods. The available surface is identical. The difference is structural: macros are procedural scripts that run once, add-ins are always-running components that react continuously.
Event handling: the first hard wall
The most common trigger for migrating is needing to respond to something SolidWorks does, rather than being manually invoked to do something. Common cases:
- Run an action every time a document opens (
DocumentAddedevent) - Log which features the user suppresses (
FeatureManagerDestroyNotify2) - Validate parts for export readiness when a rebuild completes
- Watch for the application going idle and run a background queue (
OnIdle)
Macros cannot subscribe to any of these. An event handler requires an object that stays alive to receive callbacks. When the macro exits, there is no object. The SolidWorks event model uses COM IConnectionPoint-based sinks — your subscriber must be a live COM object. An add-in implementing ISwAddin is exactly that: the ConnectToSW implementation runs once at startup and keeps the event wire alive for the session.
Engineers who need a “monitor” macro — one that watches for file changes, logs saves, or triggers actions on document events — usually discover this limit through a loop with DoEvents that appears to work but blocks the SolidWorks UI, misses events during heavy rebuilds, and fails silently on errors. That pattern is a symptom of needing an add-in architecture, not a solution.
In-process performance on large assemblies
Both VBA macros and C# add-ins call the same API methods, but where those calls originate matters for performance.
A VBA macro runs in the VBA host inside SolidWorks. API calls cross a COM apartment boundary but stay in-process. For small operations this is imperceptible.
A C# macro (.csproj-based, run via Tools → Macro → Run) runs in a separate CLR host. Calls cross both an apartment boundary and a process boundary. COM marshalling packages each argument, sends it through the inter-process channel, and unpacks it on the other side. For a handful of calls the overhead is invisible. For assembly traversal — iterating hundreds of components, reading custom properties on each, checking flat-pattern configuration state — the cost accumulates. A 500-component assembly that traverses in 2 seconds from an in-process add-in can take 3 to 5 minutes through an out-of-process standalone or C# macro.
This is well-documented in the SolidWorks API community: in-process calls have virtually no overhead beyond the method execution itself; out-of-process calls carry a per-call COM marshalling tax that scales linearly with the number of API calls in a loop. Batch export workflows — iterating assembly, flattening sheet metal, writing files per component — are the worst case for this overhead, and they are exactly the workflows where performance matters most. The in-process vs standalone API distinction is the core reason CadShift runs as an add-in rather than a scheduled script.
UI integration
A macro can appear in the SolidWorks menu via Tools → Customize → Keyboard or by placing the file on a toolbar manually. These are user-level configurations, not managed by the macro. Each user sets them up individually. They often reset after version upgrades.
An add-in creates UI programmatically in ConnectToSW:
Custom toolbars and buttons. ICommandManager.AddCommandGroup2 registers a toolbar with icon buttons bound to your commands. The button appears across sessions, for all users who have the add-in loaded, with no manual setup required.
Property Manager Pages. The IPropertyManagerPage2 interface is the most significant UI capability macros cannot provide. A PM Page is a persistent sidebar panel with input fields, dropdowns, checkboxes, sliders, and preview buttons — the same interface SolidWorks uses for Hole Wizard, Smart Fasteners, and most built-in features. Add-ins can create full PM Pages tied to specific commands. Macros approximate this with InputBox calls, which are modal, single-field, and blocking.
If your workflow involves configuring options before running — layer mappings, naming patterns, which configurations to include — a PM Page is the correct primitive. The difference in user experience between a well-designed PM Page and a chain of InputBox dialogs is significant.
Task Pane views. A persistent sidebar tab visible across documents. Add-ins register a Task Pane view during ConnectToSW; it persists for the session. Macros have no equivalent.
Distribution and maintenance
A macro is a file. Sharing it means distributing a .swp or .swb file, explaining where to put it, documenting how to add it to a toolbar, and then updating every workstation individually when you fix a bug. If paths are hardcoded, moves break it. If the file lives on a network share, concurrent access can cause lock issues.
An add-in is an installer. You compile a DLL, sign it optionally, and deploy via an .msi or silent installer. SolidWorks loads it from the registry at startup. Updates are a re-run of the installer — silent with the right flags. The VBA source is gone; the compiled DLL is harder to reverse-engineer and is version-controlled as a build artifact, not a checked-out script file.
For teams where multiple engineers use the same export workflow, this means one person maintains the codebase and everyone else gets updates automatically. With macros, keeping versions synchronized is a manual process that almost always results in different people running different versions, where “what version are you on?” is a debugging step.
When to stay with a macro
Not every script needs to become an add-in. The overhead of COM registration, ISwAddin interface implementation, and installer construction is not worth it for:
- One-off operations: Renaming files, generating a one-time report, exporting a specific configuration for a deadline
- Rapid prototyping: Validating that a workflow is feasible before investing in a full implementation
- Solo use on a single workstation: No distribution requirement, no team sharing
- Simple linear workflows: No event handling, no persistent state, no configuration UI beyond what
InputBoxcan provide
A well-named .swb file documented in the team wiki is a legitimate long-term solution for infrequent operations. The complexity budget of an add-in only pays off when the workflow is recurring, shared, or needs to integrate with SolidWorks at the event level.
The signals that say it is time
You need to respond to SolidWorks rather than be invoked by a human. Document events, rebuild notifications, idle queues — any of these require an add-in. This is the architectural boundary that cannot be worked around in macros.
It runs on more than two or three machines. Manual file distribution breaks down quickly. An installer removes the distribution problem.
Performance matters on assemblies larger than a few dozen components. If traversal takes meaningful time and you care, moving to in-process gives a 10–50× improvement on loop-heavy operations.
Users run it more than a few times per day. A toolbar button versus Tools → Macro → Run is the difference between a tool people use freely and one they use reluctantly. If it is being used daily, it deserves proper UI.
State needs to persist between invocations. Batch queues, export history, per-session configuration, progress checkpointing — all require the add-in to hold a live object between operations.
For SolidWorks automation that needs to handle VBA macro edge cases that break batch exports — suppressed configurations, multi-body parts, assemblies with external references — an in-process add-in handles these by design: it has the same assembly context SolidWorks itself has, with no marshalling boundary between the code and the model. The macro vs add-in comparison for batch DXF workflows specifically covers the implementation tradeoffs at the feature level.
The decision is not about capability in the API sense — macros can call almost everything an add-in can. It is about architecture: whether the automation lives as a one-shot script or as a first-class component of the SolidWorks session.