为SolidWorks开发VB.NET独立应用程序(exe)

在本教程中,我将演示如何使用 VB.NET 和Microsoft Visual Studio从进程外(也称为独立)应用程序(例如Windows Forms,Windows Console)连接到SOLIDWORKS应用程序。

有关本文中讨论的方法的更详细说明,请阅读《如何使用SOLIDWORKS API创建独立(exe)应用程序》一文。

创建新项目

我将使用Microsoft Visual Studio开发环境。您可以使用任何版本的 Visual Studio。相同的代码适用于专业版、精简版或社区版。

  • 打开Visual Studio。 
  • 启动新项目:

在Visual Studio中创建新的 VB.NET 项目

  • 选择项目模板。我建议从控制台应用程序项目模板开始,因为它包含最少的预生成代码:

选择 VB.NET 控制台应用程序项目模板

  • 添加对 SolidWorks 互操作库的引用。互操作库文件位于SOLIDWORKS安装文件夹\api\redist\SolidWorks.Interop.sldworks.dll(用于面向 Framework 4.0 及更高版本的项目),SOLIDWORKS安装文件夹\api\redist\CLR2\SolidWorks.Interop.sldworks.dll(用于面向框架 2.0 和 3.5 的项目)。

向项目添加程序集引用

对于面向 Framework 4.0 的项目,我建议将“嵌入互操作类型”选项设置为 false。否则,由于类型转换问题,在调用 SOLIDWORKS API 时,应用程序可能会出现不可预测的行为。 

嵌入互操作程序集的选项

现在我们可以添加代码以连接到 SOLIDWORKS 实例。

创建或连接到SOLIDWORKS实例

连接到 COM 服务器的最常见和最快速的方法可能是使用CreateObject方法(https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualbasic.interaction.createobject)。替代方法是:Activator::CreateInstance(https://learn.microsoft.com/zh-cn/dotnet/api/system.activator.createinstance)和 GetObject(https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualbasic.interaction.getobject)。请注意,如果 GetObject 无法连接到活动会话,它将创建新实例。

Const PROG_ID As String = "SldWorks.Application"

'Using Interaction.CreateObject function
Dim app1 = TryCast(CreateObject(PROG_ID), SolidWorks.Interop.sldworks.ISldWorks)
app1.Visible = True

'Using Interaction.GetObject function
Dim app2 = TryCast(GetObject("", PROG_ID), SolidWorks.Interop.sldworks.ISldWorks)
app2.Visible = True

'Using Activator
Dim progType = System.Type.GetTypeFromProgID(PROG_ID)
Dim app3 = TryCast(System.Activator.CreateInstance(progType), SolidWorks.Interop.sldworks.ISldWorks)
app3.Visible = True

我建议使用 Activator::CreateInstance,因为这允许通过 2 个步骤连接到会话:

  • 由于 SOLIDWORKS 应用程序已注册为 COM 服务器,因此我们可以通过 Type::GetTypeFromProgID方法(https://learn.microsoft.com/zh-cn/dotnet/api/system.type.gettypefromprogid)从其程序标识符创建类型。
  • 从类型定义构造类型的实例。

这种方法将在发生错误时提供更好的故障排除选项:如果第一步失败,则意味着 COM 类未注册或无法从注册表访问;否则,这可能表示存在某些权限问题。请阅读《如何使用SOLIDWORKS API创建独立(exe)应用程序》一文,了解此方法的限制说明。

或者,您可以使用 Marshal::GetActiveObject方法(https://learn.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.marshal.getactiveobject)连接到SOLIDWORKS的活动(已启动)会话。与调用 GetObject 不同,此方法将确保不会创建新的 SOLIDWORKS 实例,并且如果没有要连接的正在运行的 SOLIDWORKS 会话,则会引发异常。

Const PROG_ID As String = "SldWorks.Application"
Dim app = TryCast(System.Runtime.InteropServices.Marshal.GetActiveObject(PROG_ID),
	SolidWorks.Interop.sldworks.ISldWorks)

通过 ROT 获取正在运行的实例

为了连接到已经运行的特定 SOLIDWORKS 会话或能够创建多个会话,您可以使用正在运行的对象表 API。请阅读《如何使用SOLIDWORKS API创建独立(exe)应用程序》一文,了解有关此方法的更多详细信息。

Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.ComTypes
Imports SolidWorks.Interop.sldworks

Module CodeStackSample

    <DllImport("ole32.dll")>
    Private Function CreateBindCtx(ByVal reserved As UInteger, <Out> ByRef ppbc As IBindCtx) As Integer
    End Function

    Sub Main()

        Const SW_PATH As String = "C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\SLDWORKS.exe"

        Try
            Dim app = StartSwApp(SW_PATH)
            Console.WriteLine(app.RevisionNumber())
        Catch ex As Exception
            Console.WriteLine("Failed to connect to SOLIDWORKS instance: " & ex.Message)
        End Try

        Console.ReadLine()

    End Sub

    Function StartSwApp(ByVal appPath As String, _
            ByVal Optional timeoutSec As Integer = 10) As ISldWorks

        Dim timeout = TimeSpan.FromSeconds(timeoutSec)

        Dim startTime = DateTime.Now

        Dim prc = Process.Start(appPath)
        Dim app As ISldWorks = Nothing

        While app Is Nothing
            If DateTime.Now - startTime > timeout Then
                Throw New TimeoutException()
            End If

            app = GetSwAppFromProcess(prc.Id)
        End While

        Return app
    End Function

    Function GetSwAppFromProcess(ByVal processId As Integer) As ISldWorks

        Dim monikerName = "SolidWorks_PID_" & processId.ToString()

        Dim context As IBindCtx = Nothing
        Dim rot As IRunningObjectTable = Nothing
        Dim monikers As IEnumMoniker = Nothing

        Try

            CreateBindCtx(0, context)

            context.GetRunningObjectTable(rot)
            rot.EnumRunning(monikers)

            Dim moniker = New IMoniker(0) {}

            While monikers.[Next](1, moniker, IntPtr.Zero) = 0

                Dim curMoniker = moniker.First()
                Dim name As String = Nothing

                If curMoniker IsNot Nothing Then

                    Try
                        curMoniker.GetDisplayName(context, Nothing, name)
                    Catch ex As UnauthorizedAccessException
                    End Try

                End If

                If String.Equals(monikerName, name, StringComparison.CurrentCultureIgnoreCase) Then
                    Dim app As Object = Nothing
                    rot.GetObject(curMoniker, app)
                    Return TryCast(app, ISldWorks)
                End If

            End While

        Finally

            If monikers IsNot Nothing Then
                Marshal.ReleaseComObject(monikers)
            End If

            If rot IsNot Nothing Then
                Marshal.ReleaseComObject(rot)
            End If

            If context IsNot Nothing Then
                Marshal.ReleaseComObject(context)
            End If
        End Try

        Return Nothing

    End Function

End Module

在上面的示例中,通过从SOLIDWORKS应用程序安装路径启动新进程来启动SOLIDWORKS的新会话。StartSwApp 函数需要 sldworks.exe的完整路径作为第一个参数,可选的timeout(超时,以秒为单位)作为第二个参数。超时将确保在进程无法启动的情况下应用程序不会被锁定。

您还可以使用异步调用,以便在SOLIDWORKS启动时在应用程序中显示一些进度指示:

Private Async Function StartSwAppAsync(ByVal appPath As String, _
    ByVal Optional timeoutSec As Integer = 10) _
        As System.Threading.Tasks.Task(Of SolidWorks.Interop.sldworks.ISldWorks)
    Return Await System.Threading.Tasks.Task.Run(Function() StartSwApp(appPath, timeoutSec))
End Function

文章翻译自https://www.codestack.net/

仅供学习使用。

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空