C# SolidWorks 二次开发 -从零开始创建一个插件(1)

学习内容:从零开始定制一个SolidWorks插件

		作为了一个职业的二次开发人员,我曾经创建插件"无数"。但从未像今天这篇文章这样,从空项目开始,之前的文章中我有介绍,要么使用SolidWorks API模板,要么使用了第三方框架。但是其实这两种办法其实都太臃肿了,里面包括了太多的一些东西,比如菜单呀,事件,毕竟有时候做个小插件可能都不涉及,不需要那么多功能。
		为了更好的理解,我介绍一下从零开始定制一个插件的几个步骤,这里以VS2022来做演示,后面代码也会开源。

net farmework 版本的选择

	正常来说,Solidworks对.net Framework没有严格的要求,最新的.net 6也是可以创建插件的,只是说sw每个版本自带的.net 版本是不一样的,大家可以查看安装包里面有个PreReqs文件夹,里面可以看到对应的版本。现在win11 和一些win10上面已经默认不带.net2.0 和.net3.5了,所以目前最好的就是.net 4.0,相对来说支持的广泛一些。

打开VS2022,选择创建新项目
在这里插入图片描述
这里一定是去选择.net Framework的版本,其它的版本是不一样的。
在这里插入图片描述
这里指定框架版本,自己设置新的路径,点击 创建。

成功之后如下图:
在这里插入图片描述

dll的引用

要做SolidWorks的插件,肯定要引用官方提供的dll文件,文件在sw安装目录下面,如果不记得在哪,可以看下快捷方式的属性。

或者用电脑上的Everything软件搜索Sldworks.exe,看我这电脑上有2个版本,就能看出来两个路径。
在这里插入图片描述
至于引用哪一个版本的,好像不是太重要,因为高版本基本上向下兼容,在不调用高版本api的情况下,用低版本也可以。
我们就随便找个版本吧,进入到安装目录下\API\redist
在这里插入图片描述
这里面dll比较多,但常用的是:
在这里插入图片描述
当然还有个,上层目录下也有这几个dll
在这里插入图片描述
我们先打开项目的目录:
在这里插入图片描述
我在这里新建一个文件夹ReferenceDLL
在这里插入图片描述
然后把关键的dll复制进来
在这里插入图片描述
在这里插入图片描述
然后浏览到上面我们创建的文件夹,引用这4个dll
在这里插入图片描述
然后设置一下dll的互操作类型:
在这里插入图片描述

64位的设置

现在大部分电脑已经是64位了,如果需要生成的dll是64位的,可以这样修改:
在这里插入图片描述
在弹出的界面中选择:
在这里插入图片描述

COM的显示

在这里插入图片描述
此处要勾上。(当前也可以在类里面用属性显示定义COM可见。)

ISwAddin接口

首先重命名以前的Class1为你想要的名称,我这里改为AddinStudy.然后双击选中AddinStudy这个类,前方会出现重命名文件为xxxx.cs.
我们点一下,这样这个文件名也会变更了。

在这里插入图片描述
所以当前状态为:
在这里插入图片描述

然后,我们让这个类继承接口类ISwAddin ,前让VS自动引用对应的命名空间。
在这里插入图片描述
然后继续让VS自动实现接口:
在这里插入图片描述

此时代码就是:

 public class AddinStudy:ISwAddin
    {
        public bool ConnectToSW(object ThisSW, int Cookie)
        {
            throw new NotImplementedException();
        }

        public bool DisconnectFromSW()
        {
            throw new NotImplementedException();
        }
    }

现在里面执行都是抛异常的,所以我们来改一下。
在这里插入图片描述
然后,我们要给我们的插件加上名称的描述,不然Solidworks怎么知道插件的名称呢。
就是显示在插件管理界面里的信息。
在这里插入图片描述

这里我们就要引用 using SolidWorksTools;
然后再加上属性:
[SwAddin(
Description = “SolidWorksAddinStudy description”,
Title = “SolidWorksAddinStudy”,
LoadAtStartup = true
)]

当前完整代码:

using SolidWorks.Interop.swpublished;
using SolidWorksTools;
using System.Windows.Forms;

namespace SolidWorksAddinStudy
{
    [SwAddin(
    Description = "SolidWorksAddinStudy description",
    Title = "SolidWorksAddinStudy",
    LoadAtStartup = true
    )]
    public class AddinStudy : ISwAddin
    {
        private ISldWorks iSwApp = null;

        public ISldWorks SwApp
        {
            get { return iSwApp; }
        }

        public AddinStudy()
        {
            
        }
        public bool ConnectToSW(object ThisSW, int Cookie)
        {
            iSwApp = (ISldWorks)ThisSW;

            iSwApp.SendMsgToUser("SolidWorks正在加载此插件...");

            return true;
        }

        public bool DisconnectFromSW()
        {
            return true;
        }
    }
}

DLL注册

接下来就是要写注册表事件了,当注册dll的时候需要写一信息到注册表里面方便solidworks在下一次开启的时候可以读到插件信息。
下面的代码直接是从api帮助中拿出来的。
        #region SolidWorks Registration

        [ComRegisterFunctionAttribute]
        public static void RegisterFunction(Type t)
        {
            #region Get Custom Attribute: SwAddinAttribute

            SwAddinAttribute SWattr = null;
            Type type = typeof(**AddinStudy**);

            foreach (System.Attribute attr in type.GetCustomAttributes(false))
            {
                if (attr is SwAddinAttribute)
                {
                    SWattr = attr as SwAddinAttribute;
                    break;
                }
            }

            #endregion Get Custom Attribute: SwAddinAttribute

            try
            {
                Microsoft.Win32.RegistryKey hklm = Microsoft.Win32.Registry.LocalMachine;
                Microsoft.Win32.RegistryKey hkcu = Microsoft.Win32.Registry.CurrentUser;

                string keyname = "SOFTWARE\\SolidWorks\\Addins\\{" + t.GUID.ToString() + "}";
                Microsoft.Win32.RegistryKey addinkey = hklm.CreateSubKey(keyname);
                addinkey.SetValue(null, 0);

                addinkey.SetValue("Description", SWattr.Description);
                addinkey.SetValue("Title", SWattr.Title);

                keyname = "Software\\SolidWorks\\AddInsStartup\\{" + t.GUID.ToString() + "}";
                addinkey = hkcu.CreateSubKey(keyname);
                addinkey.SetValue(null, Convert.ToInt32(SWattr.LoadAtStartup), Microsoft.Win32.RegistryValueKind.DWord);
            }
            catch (System.NullReferenceException nl)
            {
                Console.WriteLine("There was a problem registering this dll: SWattr is null. \n\"" + nl.Message + "\"");
                System.Windows.Forms.MessageBox.Show("There was a problem registering this dll: SWattr is null.\n\"" + nl.Message + "\"");
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);

                System.Windows.Forms.MessageBox.Show("There was a problem registering the function: \n\"" + e.Message + "\"");
            }
        }

        [ComUnregisterFunctionAttribute]
        public static void UnregisterFunction(Type t)
        {
            try
            {
                Microsoft.Win32.RegistryKey hklm = Microsoft.Win32.Registry.LocalMachine;
                Microsoft.Win32.RegistryKey hkcu = Microsoft.Win32.Registry.CurrentUser;

                string keyname = "SOFTWARE\\SolidWorks\\Addins\\{" + t.GUID.ToString() + "}";
                hklm.DeleteSubKey(keyname);

                keyname = "Software\\SolidWorks\\AddInsStartup\\{" + t.GUID.ToString() + "}";
                hkcu.DeleteSubKey(keyname);
            }
            catch (System.NullReferenceException nl)
            {
                Console.WriteLine("There was a problem unregistering this dll: " + nl.Message);
                System.Windows.Forms.MessageBox.Show("There was a problem unregistering this dll: \n\"" + nl.Message + "\"");
            }
            catch (System.Exception e)
            {
                Console.WriteLine("There was a problem unregistering this dll: " + e.Message);
                System.Windows.Forms.MessageBox.Show("There was a problem unregistering this dll: \n\"" + e.Message + "\"");
            }
        }

        #endregion SolidWorks Registration


在这里,我们需要对此插件类设置Com可见,并设置一个Guid(可通过VS上面的菜单工具创建GUID来弄个新的。)

在这里插入图片描述

此时,点击生成/或者重新生成,检查 是否可以生成dll.
在这里插入图片描述
在这里插入图片描述
提示成功。
上一步我们完成了最简单的插件,我们要看一下如果注册,.net的dll都是要注册才能使用,所以这就是为什么插件会让你先注册一下,或者用安装包安装。
注册的话我们要用到regasm.exe这个文件。
大家可以Everything搜索一下,注意看,我们要用到的是64位的,v4.0的,所以我们复制这个exe到 生成的Debug目录下:
在这里插入图片描述
在这里插入图片描述
然后在这目录下新建两个bat文件,一个用于安装,一个用于卸载。(注意下面的dll 要和你生成的dll名称一样)

set path=%~d0
cd %path%
cd /d %~dp0

RegAsm.exe SolidWorksAddinStudy.dll /codebase
pause


set path=%~d0
cd %path%
cd /d %~dp0

RegAsm.exe SolidWorksAddinStudy.dll /u
pause

所以,当前Debug目录下就有像这样:
在这里插入图片描述
选中安装.bat 右击 --以管理员运行
在这里插入图片描述
检查里面是否是提示注册成功。
在这里插入图片描述
此时打开solidworks,没有意外的话会出现提示对话框
在这里插入图片描述
然后SolidWorks里面就可以看到插件了。
在这里插入图片描述

调试

先设置调试exe路径:
在这里插入图片描述

然后再这里打个断点:
在这里插入图片描述
然后直接启动,就会在Solidworks加载此dll的时候进来,这时候就可以进行调试状态了,但是这样调试的时候Solidworks里面的显示是不能动的,也无法操作。所以常用的方案是另外封装一个dll,在Exe里面进行调试,最后插件直接调用公用的dll来执行任务。

Git仓库

https://gitee.com/painezeng/SolidWorksAddinStudy

这样一个最简单的插件已经可以加载了,下篇文章再看一下怎么加载菜单吧