Skip to main content

How to run commands synchronously using SOLIDWORKS API

Opened Command (Property Manager Page){ width=250 }

ISldWorks::RunCommand SOLIDWORKS API method allows running any command. Usually it is used to open property manager page.

However this command runs asynchronously, which means that the control is returned to the executor once command started (e.g. Property Manager Page is opened). In some cases it is required to execute the code once this command closes (e.g. Property Manager Page is closed).

This example demonstrates how to run command synchronously using SOLIDWORKS API, so the control is returned to the executor once the command finishes (not started).

Run Instructions

  • Open/create part document
  • Create any sketch with rectangle (or another shape)
  • Select the sketch
  • Run the macro. As the result 'Boss-Extrude' property page is displayed
  • Modify options and click green tick (OK) or cross (Cancel)
  • Macro displays the message when property page is closed and the result (OK or Cancel) is displayed

VBA Macro

  • Create a class module and name it CommandRunManager. Copy the code below:
Dim WithEvents swApp As SldWorks.SldWorks

Dim CurrentCommandId As Long
Dim IsCommandCompleted As Boolean
Dim CloseReason As Long

Private Sub Class_Initialize()

Set swApp = Application.SldWorks

End Sub

Function RunCommand(cmd As swCommands_e) As Boolean

IsCommandCompleted = False
CurrentCommandId = cmd
swApp.RunCommand cmd, ""

While Not IsCommandCompleted
DoEvents
Wend

RunCommand = CloseReason = swCommands_e.swCommands_PmOK

End Function

Private Function swApp_CommandCloseNotify(ByVal Command As Long, ByVal reason As Long) As Long

If CurrentCommandId <> -1 Then

If Command = CurrentCommandId Then
CurrentCommandId = -1
IsCommandCompleted = True
CloseReason = reason
End If

End If

End Function
  • Copy the following code into the main module (where the main function is)
  • Modify the RunCommand to pass any other command id if needed. Method returns True if the command is closed with OK button, False is returned when command is cancelled.
Sub main()

Dim cmdsMgr As CommandRunManager
Set cmdsMgr = New CommandRunManager

If cmdsMgr.RunCommand(swCommands_Extrude) Then
MsgBox "Command Completed"
Else
MsgBox "Command Cancelled"
End If

End Sub

C#

It is not recommended to use DoEvents function to emulate async operation in .NET languages (C# or VB.NET). It is better to use Asynchronous programming with async and await

Example below demonstrates an implementation of async version of RunCommand which can be awaited without locking of the UI thread:

SldWorksExtension.cs

using SolidWorks.Interop.swcommands;
using System.Threading.Tasks;

namespace SolidWorks.Interop.sldworks
{
public static class SldWorksExtension
{
public static Task<bool> RunCommandAsync(this ISldWorks app, swCommands_e cmd)
{
return Task.Run(() =>
{
if (app.RunCommand((int)cmd, ""))
{
var isCmdCompleted = false;
var res = false;

(app as SldWorks).CommandCloseNotify += (int Command, int reason) =>
{
res = reason == (int)swCommands_e.swCommands_PmOK;
isCmdCompleted = true;
return 0;
};

while (!isCmdCompleted)
{
Task.Delay(10);
}

return res;
}

return false;
});
}
}
}

The extension can be called from any async method. For example

using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swcommands;
using System;
using System.Threading.Tasks;

namespace RunCommandAsyncConsole
{
class Program
{
static void Main(string[] args)
{
AsyncMain().Wait();
return;
}

static async Task AsyncMain()
{
var app = Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) as ISldWorks;
app.Visible = true;

var res = await app.RunCommandAsync(swCommands_e.swCommands_Extrude);

if (res)
{
app.SendMsgToUser("Command Completed");
}
else
{
app.SendMsgToUser("Command Canceled");
}
}
}
}