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

news2024/11/26 17:48:10

学习内容:从零开始定制一个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安装目录下面,如果不记得在哪,可以看下快捷方式的属性。
	![在这里插入图片描述](https://img-blog.csdnimg.cn/d40cfb2a5ef44093b2b83a762310bf3b.png)
	或者用电脑上的Everything软件搜索Sldworks.exe,看我这电脑上有2个版本,就能看出来两个路径。
	![在这里插入图片描述](https://img-blog.csdnimg.cn/eaf80318f3d1491888873b289851ed56.png)
    至于引用哪一个版本的,好像不是太重要,因为高版本基本上向下兼容,在不调用高版本api的情况下,用低版本也可以。
    我们就随便找个版本吧,进入到安装目录下\API\redist
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/d04fd163f2064562931be46535f7512b.png)
	这里面dll比较多,但常用的是:
	![在这里插入图片描述](https://img-blog.csdnimg.cn/f9e7179beb6d4a4da77bef52b607a9f1.png)
 	当然还有个,上层目录下也有这几个dll
 	![在这里插入图片描述](https://img-blog.csdnimg.cn/cc62b11c08be4aec867cbbe79fa20ef3.png)
	我们先打开项目的目录:
	![在这里插入图片描述](https://img-blog.csdnimg.cn/90b724789a824062af27bc9c37e1ee5c.png)
	我在这里新建一个文件夹ReferenceDLL
![在这里插入图片描述](https://img-blog.csdnimg.cn/a95955cbcd4d4e6b9ae9fd0d92c7d82e.png)
然后把关键的dll复制进来
![在这里插入图片描述](https://img-blog.csdnimg.cn/e2778e8dfc824ac8aecf126ca4cffbcc.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/672c90811ef44593a3a0c254c131032f.png)
然后浏览到上面我们创建的文件夹,引用这4个dll
![在这里插入图片描述](https://img-blog.csdnimg.cn/1284214b0b99480798f309d54529bc32.png)

然后设置一下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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/742686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小马哥JAVA实战营-JDBC

小马哥是一个非常牛逼的技术大牛,最近在看他的课,感兴趣也可以关注一波小马哥(不是引流,是真的很推荐): 小马哥B站 JDBC规范文档 jdbc规范文档下载链接 JDBC的主要特征 面向数据表行列编程驱动程序需要…

《3.linux应用编程和网络编程-第8部分-3.8.网络基础》 3.8.1.网络通信概述 3.8.3.网络通信基础知识2

进程间通信: 管道 、 信号量、 共享内存, 技术多,操作麻烦 线程就是解决 进程间 通信 麻烦的事情,这是线程的 优势 3.8.1.网络通信概述 3.8.1.1、从进程间通信说起:网络域套接字socket,网络通信其实就是位…

2023.7月最新版idea安装Jrebel实现热部署,可解决后端启动等待时间过长问题

2023.7最新版idea热部署配置 一 下载jrebel插件二 激活我使用的方法 三 配置方式1 设置自动编译2 设置 compiler.automake.allow.when.app.running3 勾选项目,然后以Rebel方式启动 4 Settings查看Activation情况四 报错解决1 启动失败 2 端口被占用 五 总结 一 下载…

JS 的 new 到底是干什么的?

大部分讲 new 的文章会从面向对象的思路讲起,但是我始终认为,在解释一个事物的时候,不应该引入另一个更复杂的事物。 今天我从「省代码」的角度来讲 new。 --------------------------- 想象我们在制作一个策略类战争游戏,玩家…

网络编程【网络编程基本概念、 网络通信协议、IP地址 、 TCP协议和UDP协议】(一)-全面详解(学习总结---从入门到深化)

目录 网络编程基本概念 网络通信协议 IP地址 TCP协议和UDP协议 网络编程基本概念 计算机网络 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其 外部设备,通过通信线路连接起来,在网络操作系统,网络管理软 件及网络通信协议的…

echarts图表进度条类型图

1、实现效果 左边是类别、数量,中间类似于进度条,右边是所占百分比 2、实现思路 x轴不显示,y轴的axisLabel用富文本,显示机器与台数;图表有两个数据组,分别用蓝色和灰色表示,两个柱子重合&…

Jmeter beanshell编程实例

目录 1、引言 2、需求 3、BeanShell实现 3.1、原始单元测试的java代码: 3.2、调用的RSAUtil原始方法: 3.3、使用BeanShell预处理器实现报文加密: 库导入部分: JSON报文组装: RSA加密: 3.4、取样器…

【C语言】指针进化:传参与函数(2)

莫道君行早,更有早行人。— 出自《增广贤文上集》 解释:别说你出发的早,还有比你更早的人。 这篇博客我们将会深入的理解数组传参和函数指针等指针,是非常重要的内容,学好这部分才能算真正学懂C语言。 目录 一维数组传…

【网络】socket——预备知识 | 套接字 | UDP网络通信

🐱作者:一只大喵咪1201 🐱专栏:《网络》 🔥格言:你只管努力,剩下的交给时间! 在前面本喵对网络的整体轮廓做了一个大概的介绍,比如分层,协议等等内容&#x…

UFS 14 - UFS RPMB安全读写命令

UFS 14 - UFS RPMB安全读写命令 1 SECURITY PROTOCOL IN/OUT Commands1.1 CDB format of SECURITY PROTOCOL IN/OUT commands1.2 Supported security protocols list description1.3 Certificate data description 2 CDB format of SECURITY PROTOCOL IN/OUT commands demo2.1 …

Spring Boot原理分析(一):项目启动流程、自动装配

文章目录 一、项目启动流程二、SpringBootApplication.java源码解析1.准备工作2.源码3.自定义注解4.组合注解5.注解ComponentScan过滤器 6.注解SpringBootConfigurationConfiguration 7.注解EnableAutoConfiguration(1)Spring手动装配使用XML配置文件使用…

Nerf论文阅读笔记Neuralangelo: High-Fidelity Neural Surface Reconstruction

Neuralangelo:高保真神经表面重建 公众号:AI知识物语;B站暂定;知乎同名 视频入门介绍可以参考 B站——CVPR 2023最新工作!Neuralangelo:高保真Nerf表面重建 https://www.bilibili.com/video/BV1Ju411W7…

杨氏矩阵,字符串左旋,字符串旋转结果题目解析

杨氏矩阵 题目要求:有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。 示例 分析:我们仔细分析,不难发现,对于杨氏矩阵老说,右上角和左下…

leetcode1020. 飞地的数量

https://leetcode.cn/classic/problems/number-of-enclaves/description/ 给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的…

哈希的应用->位图

ps:左移位并不是向左移动位,而是低数据位向高数据位挪动 位图(主要接口,set(size_t)标识、reset(size_t)取消、test(size_t) 查看 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一…

做软件测试到底要不要学编程?

乔布斯曾经说过“每个人都应该学习编程,因为它会教你如何思考”,看,乔帮主都觉得所有人都应该学编程,那你说做测试的要不要学?当然要。 作为测试人员,除了上面这个原因,我觉得如果会编程&#x…

Android架构之MVC,MVP,MVVM解析

MVC架构 View:Acitivity(View)、Fragment(View)视图,在android里xml布局转成View后,加载到了Activity/Fragment里了。 Controller:Controller对应着Activity/Fragment,绑定UI,处理各种业务。 Model&#xf…

python接口自动化(三十)--html测试报告通过邮件发出去——中(详解)

简介 上一篇,我们虽然已经将生成的最新的测试报告发出去了,但是MIMEText 只能发送正文,无法带附件,因此我还需要继续改造我们的代码,实现可以发送带有附件的邮件。发送带附件的需要导入另外一个模块 MIMEMultipart。还…

java版电子招标采购系统源码之电子招标采购实践与展望-招标采购管理系统

统一供应商门户 便捷动态、呈现丰富 供应商门户具备内外协同的能力,为外部供应商集中推送展示与其相关的所有采购业务信息(历史合作、考察整改,绩效评价等),支持供应商信息的自助维护,实时风险自动提示。…

springboot+MySQL实现4S店车辆管理系统

本系统为了数据库结构的灵活性所以打算采用MySQL来设计数据库,而java技术,B/S架构则保证了较高的平台适应性。本文主要介绍了本系统的开发背景,所要完成的功能和开发的过程,主要说明了系统设计的重点、设计思想。