← LibraryConnecting to SolidWorks from Visual Studio in C# and VB.NETEngineering · ComputersLesson 3/10← PrevNext →
ArticlePublished 4 Aug 20268 min readBy Kevin JoginSolidWorks APIC#VB.NETCOM interop

Engineering / Computers / Part 2 of 9

Connecting from Visual Studio

Moving from a macro to a compiled .NET program changes almost nothing about the API calls and almost everything about the plumbing around them. The logic transfers in an afternoon; the references, casting rules and object lifetime are where the days go if nobody has told you what to expect.

  • Part 2 · Tooling
  • Interop settings
  • Attach vs launch
  • COM lifetime

KL-ENG-COMP-1502 · KEVOS® Knowledge Library · Australian English

A macro is handed the application object because it runs inside the SOLIDWORKS process. An external program is not. It has to locate a running session through COM, or start one, and then work with objects that live in another process across an interop boundary. Everything distinctive about .NET SOLIDWORKS programming follows from that.

3Interop assemblies to reference
2Project settings that cause most first-run failures
1Program identifier used to find a session

01Why leave the macro editor

The Visual Basic editor inside SOLIDWORKS is a capable environment for small tools. Four things push work out of it.

Real user interfaces

Multi-control windows, file dialogues, progress reporting, lists and trees — none of which the macro environment offers convincingly.

Access to everything else

Databases, spreadsheets, web services, version control, unit-testing frameworks and modern libraries. Automation rarely stays confined to CAD for long.

Compilation and type safety

Errors surface at build time rather than halfway through a batch of two hundred files.

The path to add-ins

An add-in is a .NET library. Everything you learn building a stand-alone client carries directly into Part 9.

02Project setup and the two settings that matter

Create a desktop application project, then add references to the SOLIDWORKS interop assemblies. They are installed alongside SOLIDWORKS, and they are also published as packages you can restore.

SolidWorks.Interop.sldworks
The main object model — application, documents, features, components, selections, managers.
SolidWorks.Interop.swconst
Every enumeration. Reference members by name from here rather than using integers.
SolidWorks.Interop.swpublished
Interfaces you implement rather than call — the PropertyManager page handler and the add-in contract. Needed from Part 5 onward.
Set these two, or nothing works

On each SOLIDWORKS interop reference, set Embed Interop Types to False. The default is True, and with it enabled the calls appear to compile but fail at run time in ways that are difficult to interpret. Setting Copy Local to False as well avoids shipping a copy of the interop that then disagrees with the installed release.

Platform target

SOLIDWORKS is a 64-bit application. A client that attaches to it must be built for a matching architecture — either 64-bit explicitly, or a neutral target that will run as 64-bit on a 64-bit operating system. A 32-bit build is one of the more common causes of an attach that fails with an unhelpful message.

03Attaching to a running session

COM identifies registered applications by a program identifier. For SOLIDWORKS this is a stable string, and there are release-specific variants alongside it. Ask the running-object table for the current instance.

C#attach, with the failure case handled
using SolidWorks.Interop.sldworks;
using System.Runtime.InteropServices;

ISldWorks swApp = null;

try
{
    swApp = (ISldWorks)Marshal.GetActiveObject("SldWorks.Application");
}
catch (COMException)
{
    // Nothing registered under that identifier: no session is running,
    // or it is running under a different user or elevation level.
    swApp = null;
}

if (swApp == null)
{
    MessageBox.Show("Start SOLIDWORKS, then run this tool again.");
    return;
}

Two behaviours are worth committing to memory.

  • Failure is an exception, not a null return. Calling without a try/catch produces an unhandled exception the first time the tool is run before SOLIDWORKS — which is exactly when a new user will run it.
  • Elevation must match. A program running as administrator will not find a session started by a normal user, and the reverse is equally true. The symptom is an attach that fails while SOLIDWORKS is visibly open on screen.
On newer .NET

The convenience wrapper for retrieving a running object is a .NET Framework facility and is not available in every newer runtime. Where it is absent, the same result is obtained by calling the underlying operating system function that reads the running-object table. The concept is unchanged; only the helper differs. Confirm what your chosen target framework supports before committing to it.

04Starting a session when none is running

For unattended batch work, requiring a user to have SOLIDWORKS already open defeats the purpose. Create an instance from the program identifier instead.

C#launch, then make visible
var swType = System.Type.GetTypeFromProgID("SldWorks.Application");
var swApp  = (ISldWorks)System.Activator.CreateInstance(swType);

swApp.Visible = true;   // omit for a genuinely headless batch run

A newly created instance starts hidden. Leaving it hidden is right for a scheduled export job and wrong for anything a user is watching, because a hidden session that prompts for input appears to hang.

Licensing and shutdown

Every instance you start consumes a licence and keeps consuming it until the process ends. A batch tool that starts a session must also close it, on the failure path as well as the success path. Wrapping the whole run so that shutdown happens regardless of outcome is not optional — orphaned processes accumulate silently and exhaust licences at the worst possible time.

Attach or launch — choosing between them
SituationApproachReason
User is modelling and wants a toolAttachActs on what is already open; no second session, no second licence
Scheduled overnight batchLaunchNo user present; the tool controls the whole lifecycle
Either might applyAttach, fall back to launchTry to attach; on failure create an instance and record which path was taken
Tool must never disturb the userAttach onlyLaunching a second session while one is open confuses everyone

05Casting, and why so much is returned as object

A great many API members are declared as returning a generic object. This is a consequence of the interface being COM-based and having evolved over decades, and it means explicit casting is a constant feature of .NET SOLIDWORKS code.

C#cast, then test — in that order
IModelDoc2 swModel = swApp.ActiveDoc as IModelDoc2;
if (swModel == null) { /* nothing open */ return; }

// Type-specific behaviour comes from casting the same handle again.
if (swModel.GetType() == (int)swDocumentTypes_e.swDocASSEMBLY)
{
    IAssemblyDoc swAssy = (IAssemblyDoc)swModel;
    // ... assembly-only members are now reachable
}

Prefer the safe cast that yields null over the hard cast that throws, then test the result. Failures here are usually a wrong assumption about document type rather than a genuinely exceptional condition, and a null test expresses that more honestly than an exception handler.

Arrays arrive as object

Members that return collections — configuration names, sheet names, child components — return an object that must be cast to an array before use. In VB.NET and VBA the conversion is implicit and the same code reads more simply; in C# the cast is explicit. This is the largest surface-level difference between the two languages when using this API, and it is cosmetic rather than functional.

06COM object lifetime

Every API object your program holds is a wrapper around something owned by the SOLIDWORKS process. The wrapper is managed by .NET; the object behind it is not. That asymmetry is the source of the most puzzling defects in .NET CAD automation.

The symptom

SOLIDWORKS refuses to close cleanly, or the process persists after the window disappears, or a file stays locked after processing. Almost always, a reference is still outstanding.

The cause

References are released when the garbage collector runs, which is at a time of its choosing. Until then, the other process considers the object in use.

The discipline

Release references explicitly when you are finished with them, particularly inside loops that process many documents, and null the variable afterwards.

The judgement

Do not release something you did not obtain, and do not release an object you will use again. Over-releasing produces failures that are harder to diagnose than the leak it was meant to prevent.

Practical rule

For a tool that opens one document and exits, ordinary cleanup is sufficient. For a tool that opens, processes and closes documents in a loop, release each document reference at the end of each iteration. The difference between the two patterns shows up at about the fiftieth file.

07Troubleshooting the first run

First-run failures and what they usually mean
What you seeMost likely causeAction
Attach throws, SOLIDWORKS is openElevation mismatch, or a 32-bit buildRun both at the same level; confirm the platform target
Compiles, fails at the first callEmbed Interop Types left enabledSet it to False on every SOLIDWORKS interop reference
Members missing from completionInterop version does not match the installed releaseReference the interops from the installed release
Cast fails on a returned objectAssumed document type is wrongTest the document type before casting
SOLIDWORKS will not closeOutstanding COM referencesRelease references explicitly; null the variables
Works on the developer machine onlyAbsolute paths, or an interop copied alongside the executableRead paths from preferences; set Copy Local to False
Record the environment

Note the SOLIDWORKS release, the interop version, the target framework and the platform target in the project's own documentation. When the tool eventually breaks on a new release, this half-page is what makes the diagnosis take an hour instead of a day.

08Quick reference

SldWorks.Application
The program identifier used to attach to or create a session. Release-specific variants exist.
Marshal.GetActiveObject
Retrieves a running instance. Throws when none is registered — always wrap it.
Type.GetTypeFromProgID + Activator.CreateInstance
Creates a new instance when no session is running. Starts hidden.
ISldWorks::Visible
Shows or hides a session you created. Leave hidden only for genuinely unattended work.
ISldWorks::ExitApp
Closes a session your tool started. Call it on every exit path.
Embed Interop Types = False
Required on every SOLIDWORKS interop reference.
Copy Local = False
Prevents shipping an interop that disagrees with the installed release.
Marshal.ReleaseComObject
Releases a reference deterministically. Use inside loops; do not over-apply.

Continue learning

SolidWorks API Macro Fundamentals: Recording, Reading and WritingArticle · ComputersNEXT LESSON →First SolidWorks Automation Tasks: Batch Export and Document InformationArticle · ComputersSolidWorks API Programming and Automation: Series OverviewArticle · ComputersWorking with Selected Objects in the SolidWorks APIArticle · Computers