SolidWorks二次开发模板:基于.NET Framework的可交付插件工程化实践

简介:本资源是一套开箱即用的SolidWorks C#二次开发模板工程,面向机械设计工程师、CAD自动化开发者及高校相关专业学习者,解决从零搭建插件项目、理解SDK交互机制与快速实现功能扩展的入门难题。压缩包含99个文件,涵盖18个核心C#源码(.cs)、2个Visual Studio解决方案(.sln)与项目文件(.csproj)、34个运行依赖DLL、6个工具栏图标(.bmp)及5个资源文件(.resx),完整呈现插件初始化、事件响应、界面集成与命令注册等关键模块结构;整体大小为10.24MB,结构清晰,便于逐层剖析与二次定制。已有728人学习下载,提供可直接编译运行的SwCSharpAddin1示例项目,包含Windows Forms界面、SolidWorks事件处理(EventHandling.cs)、属性管理页(UserPMPage.cs)、操作封装类(Solidworks操作.cs)及多级菜单/工具栏图标配置,助开发者快速掌握COM Add-in开发全流程与工程化实践要点。

1. SolidWorks二次开发模板:不是写个宏就叫“开发”,而是让设计流程真正可复用、可交接、可维护

很多同学交毕设或做课设时,一听说“SolidWorks二次开发”,第一反应是录个宏、改两行VBA、导出一个.dll——结果答辩被问“这个插件怎么部署到另一台电脑?”“参数改了要不要重编译?”“别人接手你的代码能看懂逻辑吗?”当场卡壳。这不是开发,是临时脚本。真正的SolidWorks二次开发模板,核心不是“能跑”,而是解决三个现实痛点:工程环境一致性(不同版本SolidWorks+不同.NET框架+不同Windows系统)、功能模块可插拔(比如今天加BOM生成,明天换图纸批量打印,不牵一发而动全身)、交付物即开即用(双击安装包→自动注册→菜单栏出现图标→点开就能用)。这套模板就是为某高校机械专业课程设计和某制造企业内部工具孵化场景打磨出来的——它不教你怎么画齿轮,而是确保你写的第一个“自动生成螺栓孔表”功能,三年后还能在新装的SolidWorks 2025上一键启用,且A同学写的参数校验模块,B同学能直接引用、修改、测试,不用从头翻API文档。如果你正卡在“写完代码不知道怎么打包”“调试时弹窗报错但日志没输出”“导师说‘结构太散,看不出主入口在哪’”,那这份模板就是你缺的那张工程化底图。

2. 开发环境与技术栈选型:为什么坚持.NET Framework 4.7.2 + C# + COM Interop,而不是.NET Core/NET6+

SolidWorks官方API至今(截至2024年中)仍强绑定COM组件模型,所有IDispatch接口、ISwModelDoc2、ISwAssemblyDoc等核心对象,本质都是Windows原生COM对象。这意味着:任何试图绕过COM、用纯.NET Standard封装API的方案,在加载装配体、遍历特征树、调用FeatureManager时大概率触发InvalidCastException或COMException: 0x80040154(类未注册)。这不是版本兼容问题,是架构级不匹配。我带过的两个项目曾踩坑:一个团队强行用.NET 6+COM-interop桥接,结果在SolidWorks后台静默崩溃,无日志、无dump;另一个用Python+pywin32调用,功能能跑,但每次SolidWorks重启后插件丢失注册,用户得手动运行regsvr32——这在产线环境等于不可用。

2.1 开发环境硬性约束清单(实测通过)

项目要求说明
SolidWorks版本2019 SP5 及以上(推荐2022 SP3+)2018及更早版本对.NET 4.7.2支持不稳定,SP5是分水岭;2022+版本修复了大量COM回调线程安全问题
.NET Framework必须为4.7.2(非4.8,非Core)4.7.2是SolidWorks SDK文档明确标注的最低兼容版本;4.8虽能编译,但在某些Windows Server 2016环境下触发TypeLoadException;.NET Core/6/7/8完全不支持COM互操作中的[ComSourceInterfaces]特性
Visual StudioVS 2019 16.11.x 或 VS 2022 17.4.x需启用“使用托管兼容模式”(Tools → Options → Debugging → General → Enable native code debugging),否则断点无法进入SolidWorks回调函数
Windows系统Windows 10 20H2 或 Windows 11 21H2+Windows 7已终止支持,且其COM安全策略导致插件注册失败率超60%

提示:不要在虚拟机里调试!SolidWorks对显卡驱动、DirectX版本敏感,VMware/VirtualBox的虚拟显卡常触发SwApp::GetActiveDoc()返回null。真机调试是唯一可靠方式。

2.2 模板核心项目结构解析(VS解决方案层级)

模板采用“三项目协同”结构,而非单个exe或dll:

SolidWorksAddIn.Template.sln ├── AddIn.Core (Class Library, .NET Framework 4.7.2) │ ├── Commands\ ← 所有ICommandGroup命令实现(如“生成BOM”按钮) │ ├── Handlers\ ← SolidWorks事件监听器(DocumentOpen, FileSaveAs等) │ ├── Services\ ← 业务逻辑层(BomGenerator.cs, DrawingBatchPrinter.cs) │ └── Properties\ │ └── AssemblyInfo.cs ← 关键:[assembly: Guid("...")] 必须与注册表一致 ├── AddIn.Setup (Setup Project, VS Installer Projects扩展) │ └── Product.wxs ← WiX工具集生成MSI,含注册表项、文件复制、.NET Framework检查 └── AddIn.Test (Unit Test Project, NUnit 3.13) └── IntegrationTests.cs ← 启动SolidWorks进程进行真实API调用测试(非Mock)

这种结构的价值在于:Core项目专注业务,Setup项目解决“交付”,Test项目验证“行为”。比如BomGenerator.cs只处理数据逻辑(读取特征→过滤螺栓→生成DataTable),不碰UI或SolidWorks实例;而Commands\GenerateBomCommand.cs只负责响应点击、调用Service、显示MessageBox——职责彻底分离。某次给某实验室交付时,他们要求把BOM导出格式从Excel换成PDF,我们只改了Services\BomGenerator.cs里的导出方法,其余代码零改动。

2.3 COM注册机制:为什么不用regasm,而用WiX自定义操作

很多教程教用regasm /codebase YourAddIn.dll注册,这是危险操作:

  • regasm会将dll路径硬编码进注册表,一旦用户移动文件夹,插件失效;
  • 它绕过Windows Installer事务,卸载时注册表残留严重;
  • 不检查.NET Framework是否已安装,用户双击安装包直接报错。

模板采用WiX(Windows Installer XML)生成MSI安装包,关键注册表项如下(Product.wxs片段):

<!-- SolidWorks插件注册表项 --> <Component Id="SolidWorksAddInReg" Guid="*"> <RegistryKey Root="HKLM" Key="SOFTWARE\SOLIDWORKS\AddIns\{A1B2C3D4-E5F6-7890-G1H2-I3J4K5L6M7N8}"> <RegistryValue Type="integer" Name="Description" Value="0" /> <RegistryValue Type="integer" Name="Title" Value="0" /> <RegistryValue Type="integer" Name="LoadAtStartup" Value="1" /> <!-- 1=开机加载 --> </RegistryKey> </Component> <!-- .NET COM类注册 --> <Component Id="DotNetComReg" Guid="*"> <File Id="AddInCoreDll" Source="$(var.AddIn.Core.TargetPath)" KeyPath="yes" /> <Class Id="{A1B2C3D4-E5F6-7890-G1H2-I3J4K5L6M7N8}" Context="InprocServer32" Description="SolidWorks AddIn Core" ThreadingModel="Both"> <ProgId Id="AddIn.Core.SwAddIn" Description="SolidWorks AddIn Core" /> </Class> </Component>

这里{A1B2C3D4-...}是AssemblyInfo.cs中[assembly: Guid("...")]的值,必须完全一致,否则SolidWorks启动时找不到插件入口。WiX在安装时自动执行regsvr32 /s并写入注册表,卸载时自动清理——这才是企业级交付该有的健壮性。

3. 核心功能模块设计:从“Hello World”到可扩展插件系统的四层抽象

模板不是让你写一个“弹窗说Hello”的demo,而是构建一个可随项目演进而自然生长的插件骨架。我们按抽象层级划分为四层:基础接入层、事件驱动层、命令管理层、业务服务层。每一层都提供基类和契约接口,强制规范扩展方式。

3.1 基础接入层:SwAddInBase——所有插件的唯一入口点

SolidWorks加载插件时,只会调用ISwAddIn接口的ConnectToSW方法。模板中SwAddInBase类封装了所有初始化逻辑:

// AddIn.Core\SwAddInBase.cs public abstract class SwAddInBase : ISwAddIn { protected SldWorks SwApp { get; private set; } protected ModelDoc2 ActiveDoc { get; private set; } public void ConnectToSW(object ThisSW, int Cookie) { SwApp = (SldWorks)ThisSW; // 关键:设置COM线程模型为STA,否则后续调用崩溃 if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) throw new InvalidOperationException("SolidWorks AddIn must run in STA thread"); // 订阅SolidWorks全局事件(必须在此处注册,否则事件不触发) SwApp.OnDocumentOpenNotify += OnDocumentOpen; SwApp.OnFileSaveAsNotify += OnFileSaveAs; // 初始化命令组(菜单/工具栏) InitializeCommandGroups(); // 子类可覆写此方法做自定义初始化 OnConnected(); } protected virtual void OnConnected() { } // 空实现,供子类扩展 private void InitializeCommandGroups() { // 创建顶层命令组(如“我的工具”菜单) var cmdGroup = SwApp.CreateCommandGroup(1, "我的工具", "", -1, ""); cmdGroup.LargeIconList = LoadIconResource("Resources.large_icon.bmp"); cmdGroup.SmallIconList = LoadIconResource("Resources.small_icon.bmp"); // 注册所有继承自ICommand的命令(自动发现) var commandTypes = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(typeof(ICommand))); foreach (var type in commandTypes) { var cmd = (ICommand)Activator.CreateInstance(type); cmd.Register(cmdGroup); // ICommand接口定义Register方法 } } }

这段代码的关键设计点:

  • 强制STA线程模型检查:避免90%的“调用时崩溃”问题;
  • 事件订阅前置:OnDocumentOpenNotify等事件必须在ConnectToSW内注册,晚一秒都不行;
  • 命令组自动发现:只要类实现ICommand接口,就会被自动注册到菜单,无需手动维护列表——新增一个“批量重命名零件”功能,只需新建RenamePartsCommand.cs并实现ICommand,编译后自动出现在菜单。

3.2 事件驱动层:SwEventRouter——解耦事件与业务逻辑

SolidWorks事件(如OnDocumentOpenNotify)是int类型回调,直接在SwAddInBase里写业务逻辑会导致类臃肿且无法单元测试。模板引入事件路由器模式:

// AddIn.Core\Handlers\SwEventRouter.cs public class SwEventRouter { private readonly List<IEventHandler> _handlers = new(); public void RegisterHandler<T>(IEventHandler<T> handler) where T : class { _handlers.Add(handler); } // SolidWorks事件回调入口(由SwAddInBase调用) public void OnDocumentOpen(string docName, int docType, int errors) { var @event = new DocumentOpenEvent { DocName = docName, DocType = docType }; DispatchEvent(@event); } private void DispatchEvent<T>(T @event) where T : class { foreach (var handler in _handlers.OfType<IEventHandler<T>>()) { try { handler.Handle(@event); } catch (Exception ex) { // 统一日志记录,不抛出,避免阻塞SolidWorks主线程 Log.Error($"Event handler {handler.GetType().Name} failed", ex); } } } } // 业务处理器示例:当打开装配体时,自动检查配置 public class AssemblyConfigChecker : IEventHandler<DocumentOpenEvent> { public void Handle(DocumentOpenEvent @event) { if (@event.DocType == (int)swDocumentTypes_e.swDocASSEMBLY) { var doc = SwAddInBase.Instance.SwApp.ActiveDoc as AssemblyDoc; if (doc != null && !doc.CustomInfo2["", "CheckedByTemplate"].Equals("true")) { MessageBox.Show($"装配体 {@event.DocName} 未通过模板检查,请运行'检查配置'命令"); } } } }

这样设计的好处:

  • 事件处理可测试:AssemblyConfigChecker不依赖SolidWorks实例,用Moq模拟DocumentOpenEvent即可单元测试;
  • 错误隔离:某个处理器崩溃不会影响其他处理器;
  • 热插拔:运行时可动态RegisterHandler新处理器,适合后期扩展。

3.3 命令管理层:ICommand接口与CommandAttribute

所有菜单/工具栏命令必须实现ICommand,并通过CommandAttribute声明元数据:

// AddIn.Core\Commands\ICommand.cs public interface ICommand { void Register(CommandGroup cmdGroup); void OnClick(); void OnMenuPreShow(); // 菜单显示前调用,用于动态启禁用 } // AddIn.Core\Attributes\CommandAttribute.cs [AttributeUsage(AttributeTargets.Class)] public class CommandAttribute : Attribute { public string MenuText { get; } public string ToolTip { get; } public int Position { get; } // 在菜单中的位置序号 public bool EnabledByDefault { get; set; } = true; public CommandAttribute(string menuText, string toolTip, int position) { MenuText = menuText; ToolTip = toolTip; Position = position; } } // 使用示例 [Command("生成BOM表", "为当前装配体生成Excel格式BOM", 1)] public class GenerateBomCommand : ICommand { public void Register(CommandGroup cmdGroup) { var cmd = cmdGroup.AddCommandItem2( MenuText, Position, ToolTip, -1, // 图标索引 (int)swCommandItemType_e.swMenuItem, null, 0, 0); cmd.SetBitmaps(-1, -1); // 使用命令组预设图标 } public void OnClick() { // 业务逻辑委托给Service层 var generator = new BomGenerator(SwAddInBase.Instance.SwApp.ActiveDoc); var result = generator.Generate(); MessageBox.Show($"BOM生成完成,共{result.Rows.Count}行"); } public void OnMenuPreShow() { // 动态控制菜单可用性:仅当活动文档是装配体时启用 var activeDoc = SwAddInBase.Instance.SwApp.ActiveDoc; var isEnabled = activeDoc?.GetType() == typeof(AssemblyDoc); // 这里需调用SolidWorks API设置菜单状态(略,见模板源码) } }

CommandAttribute让命令元数据集中管理,Register方法统一处理图标、位置、分组,OnClick只专注业务——这是避免“一个命令类300行,全是WinForm控件拖拽代码”的关键防线。

4. 避坑指南:SolidWorks二次开发中最容易翻车的5个致命点

SolidWorks二次开发的“玄学”感,往往来自几个看似微小、实则致命的细节。这些不是理论问题,是我在三个实际项目中亲手填过的坑,每一条都附带现场日志和修复方案。

4.1 现象:插件安装后菜单不显示,但注册表里有条目

原因:AssemblyInfo.cs中的[Guid]与WiX注册表项中的{...}不一致,或[ComVisible(true)]未添加到程序集级别。SolidWorks查找插件时,先读注册表获取CLSID,再用该CLSID查询HKCR\CLSID\{...}\InprocServer32下的DLL路径,最后加载DLL并查询[Guid]属性。若两者不符,加载失败且无提示。
解决:

  1. 用oleview.exe(Windows SDK工具)打开已安装的DLL,查看“Coclass”节点下的GUID是否与AssemblyInfo.cs一致;
  2. 确保AssemblyInfo.cs包含:
[assembly: ComVisible(true)] [assembly: Guid("A1B2C3D4-E5F6-7890-G1H2-I3J4K5L6M7N8")]
  1. WiX中<Class Id="...">的值必须与此GUID完全相同(包括大小写)。

4.2 现象:调用FeatureManager::FeatureGetByName("Extrude1")返回null,但特征名确实存在

原因:SolidWorks特征名在不同语言系统下不同。中文版叫“拉伸1”,英文版叫“Extrude1”,而API返回的是当前系统语言名。硬编码字符串必然失败。
解决:永远不用特征名定位,改用特征类型+序号:

// 错误:依赖语言 var feat = model.FeatureByName("Extrude1"); // 正确:用类型过滤 var features = model.FeatureByType((int)swFeatureNameID_e.swFeatureNameExtrude); if (features.Length > 0) { var firstExtrude = features[0]; // 获取第一个拉伸特征 }

4.3 现象:多线程调用SwApp.NewDocument()崩溃,错误码0x8001010E(RPC_E_WRONG_THREAD)

原因:SolidWorks COM对象严格绑定创建它的STA线程。在Task.Run或BackgroundWorker中调用API,必然跨线程失败。
解决:所有SolidWorks API调用必须在主线程(即SwAddInBase.ConnectToSW所在的线程)。如需异步,用Control.Invoke(WinForm)或Dispatcher.Invoke(WPF):

// 在WPF UserControl中 private void StartLongProcess() { var task = Task.Run(() => HeavyCalculation()); // 纯计算,不碰API task.ContinueWith(t => { // 回到UI线程调用SolidWorks API Dispatcher.Invoke(() => { SwApp.NewDocument("part", (int)swDocumentTypes_e.swDocPART, 0, 0); }); }, TaskScheduler.FromCurrentSynchronizationContext()); }

4.4 现象:ModelDoc2::CreateDrawings()生成的工程图,视图比例总是1:1,无法修改

原因:CreateDrawings方法创建的是“空白图纸”,不包含任何视图。必须手动添加视图并设置比例:

// 错误:以为CreateDrawings会自动加视图 var drawing = SwApp.CreateDrawings(...) as DrawingDoc; // 正确:创建后立即添加视图 var view = drawing.CreateDrawViewFromModelView3( "C:\\path\\to\\part.sldprt", "*Front", // 视图名称 0, 0); // X,Y坐标 view.ScaleDecimal = 0.5m; // 设置比例为1:2

4.5 现象:插件卸载后,SolidWorks启动仍报“无法加载插件”,重启无效

原因:WiX安装包未正确清理HKLM\SOFTWARE\SOLIDWORKS\AddIns\{...}注册表项,或InprocServer32子键残留。
解决:在WiX的Product.wxs中,为卸载添加自定义操作:

<CustomAction Id="UnregisterAddIn" BinaryKey="CustomActionBinary" DllEntry="UnregisterAddIn" Execute="deferred" Return="check" /> <InstallExecuteSequence> <Custom Action="UnregisterAddIn" Before="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom> </InstallExecuteSequence>

并在CustomActionBinary.dll中实现UnregisterAddIn函数,显式删除注册表键——不能依赖WiX默认行为。

5. 构建、调试与验收:从代码提交到用户双击安装的完整流水线

验收不是“能跑就行”,而是确保从开发者机器到最终用户桌面,整个链路零人工干预、零环境假设、零隐藏依赖。这套模板的验收标准,是我给某制造企业交付时定死的红线,现在直接搬给你用。

5.1 构建流程:三步生成可交付MSI

模板根目录下提供build.ps1PowerShell脚本,全自动完成:

  1. 清理与编译:调用msbuild编译Core和Test项目,生成AddIn.Core.dll;
  2. WiX编译:用candle.exe编译Product.wxs,用light.exe链接生成AddIn.msi;
  3. 签名与压缩:用signtool.exe对MSI数字签名(企业必备),7z压缩为AddIn_v1.0.0.7z。

执行命令:

# 在管理员PowerShell中运行 .\build.ps1 -Configuration Release -Version 1.0.0 -SignCertPath "cert.pfx" -SignPassword "123456"

输出物:dist\AddIn_v1.0.0.msi(约8MB)和dist\AddIn_v1.0.0.7z(含安装说明PDF)。

注意:build.ps1内置.NET Framework 4.7.2检查,若目标机器未安装,脚本自动下载离线安装包并静默安装——这是避免“用户装不上”的最后一道保险。

5.2 调试黄金组合:VS断点 + SolidWorks日志 + Windows事件查看器

单靠VS断点无法覆盖所有场景。必须三管齐下:

  • VS断点:只对SwAddInBase.ConnectToSW、ICommand.OnClick等入口点设断点;
  • SolidWorks日志:启动SolidWorks时加命令行参数/log "C:\swlog.txt",日志会记录插件加载过程、COM调用失败详情;
  • Windows事件查看器:筛选“应用程序”日志,关键词SolidWorks或AddIn.Core,COM异常会以Error级别记录,含堆栈片段。

典型调试流:

  1. 用户报告“点击BOM按钮无反应”;
  2. 查swlog.txt,发现Failed to load AddIn.Core, HRESULT: 0x80070002(文件未找到);
  3. 查事件查看器,看到Could not load file or assembly 'System.Data.SQLite, Version=1.0.115.0';
  4. 定位到BomGenerator用了SQLite存缓存,但WiX未打包System.Data.SQLite.dll;
  5. 在Product.wxs中添加该DLL的<File>项,重新构建。

5.3 验收检查表(答辩/交付前必过)

检查项通过标准工具/方法
环境兼容性在SolidWorks 2022 SP3 + Win10 21H2 + .NET 4.7.2纯新装机上,双击MSI→完成安装→启动SolidWorks→菜单栏出现“我的工具”真机测试,禁用所有杀毒软件
功能完整性所有ICommand注册的菜单项均可见、可点击;点击后无崩溃,有合理反馈(MessageBox或状态栏提示)手动逐项点击,记录响应时间(应<2秒)
错误防御性强制关闭SolidWorks进程后重启,插件仍能加载;打开非装配体文档时,“生成BOM”菜单项自动灰显模拟异常场景
日志完备性C:\Users\[User]\AppData\Local\AddIn.Template\logs\下存在debug.log,含INFO/ERROR级别日志,时间戳精确到毫秒查看日志文件内容
卸载干净度控制面板卸载MSI后,regedit中HKLM\SOFTWARE\SOLIDWORKS\AddIns\下对应项消失,C:\Program Files\AddIn.Template\文件夹清空卸载后立即检查注册表和磁盘

5.4 答辩技巧:如何用3分钟讲清楚你的“二次开发”不是脚本

答辩时,老师最怕听到“我录了个宏,改了两行代码”。你要用结构化叙事证明工程能力:

  1. 第一句话定调:“这不是宏录制,而是一个遵循SOLID原则的插件系统,核心是解耦——UI命令、业务逻辑、SolidWorks交互三层分离。”
  2. 展示一张图:拿出SwAddInBase类图(UML),指出ICommand和IEventHandler如何作为契约接口,让新增功能不修改原有代码;
  3. 演示一个对比:打开GenerateBomCommand.cs,高亮OnClick()中只有一行new BomGenerator(...).Generate(),然后打开BomGenerator.cs,说明“所有算法、Excel导出、数据校验都在这里,和SolidWorks无关”;
  4. 甩出证据:打开dist\文件夹,指着AddIn_v1.0.0.msi说:“这是标准Windows Installer包,双击即装,含.NET Framework检测和静默安装,符合企业IT策略。”

从那以后我每次带学生做SolidWorks课设,都强制他们在第一天就跑通build.ps1,生成第一个MSI,哪怕里面只有“Hello World”命令。因为真正的开发,始于可交付,而非可编译。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

Linux磁盘I/O监控:iostat与iotop实战排查

Linux磁盘I/O监控:iostat与iotop实战排查

1. 为什么需要监控磁盘 I/O&#xff1a;从一次“查不出原因的卡顿”说起你有没有遇到过这种情况&#xff1a;应用响应突然变慢&#xff0c;CPU 和内存占用却都在正常范围内&#xff0c;看日志也没报错&#xff0c;可服务就是像陷在泥潭里一样。排查到最后才发现&#xff0c;罪魁…

2026/10/20 20:10:32 阅读更多 →
一文梳理AI Infra知识全景:算力、存储、训练、推理与平台

一文梳理AI Infra知识全景:算力、存储、训练、推理与平台

做AI项目做了几年&#xff0c;我一直有个很尴尬的处境&#xff1a;模型结构、损失函数、调参技巧这些聊起来头头是道&#xff0c;可一旦扯到GPU集群怎么规划、数据管线为什么卡住、推理服务为什么线上长尾延迟爆炸&#xff0c;就有点心虚。直到有一次亲手把一个训练任务搞挂&am…

2026/10/20 20:10:32 阅读更多 →
从模糊命名到清晰边界:以rea为例谈代码可维护性重构

从模糊命名到清晰边界:以rea为例谈代码可维护性重构

1. 从“rea”这个标题说起&#xff1a;一个被低估的缩写背后藏着什么第一次看到“rea”这个标题的时候&#xff0c;我承认自己愣了几秒。没有正文&#xff0c;没有关键词&#xff0c;没有摘要描述&#xff0c;就孤零零三个字母。但恰恰是这种极简的输入&#xff0c;反而让我觉得…

2026/10/20 20:10:32 阅读更多 →

最新新闻

鸿蒙ArkTS生鲜超市实战项目解析与避坑指南

鸿蒙ArkTS生鲜超市实战项目解析与避坑指南

简介&#xff1a;本资源是一套基于华为鸿蒙操作系统&#xff08;HarmonyOS&#xff09;开发的生鲜超市行业应用实战项目&#xff0c;面向Android开发者转型鸿蒙生态、高校学生学习分布式应用开发及企业级HarmonyOS项目实践者。项目聚焦线上线下融合购物场景&#xff0c;完整呈现…

2026/10/20 20:58:45 阅读更多 →
Chrome链接总是覆盖当前页?教你设置自动在新标签页打开

Chrome链接总是覆盖当前页?教你设置自动在新标签页打开

"每次点链接都把当前页覆盖掉&#xff0c;后来越来越烦"——这个需求我收到过太多次了。Chrome 默认点击链接就在当前标签页打开&#xff0c;想在新标签页打开&#xff0c;要么按着 Ctrl 点&#xff0c;要么右键菜单选"在新标签页中打开链接"。一次两次还行…

2026/10/20 20:58:45 阅读更多 →
LMDeploy实战:开源大模型量化、推理与OpenAI兼容服务部署

LMDeploy实战:开源大模型量化、推理与OpenAI兼容服务部署

这段时间一直在折腾开源大模型的落地部署&#xff0c;试了不少推理框架&#xff0c;最后在业务环境里稳定跑下来的是 LMDeploy。如果你也在做类似的事情——想把 Qwen、Llama 这类开源模型接到自己的系统里&#xff0c;或者想在项目里做一个带 API 的聊天服务&#xff0c;那么这…

2026/10/20 20:58:45 阅读更多 →
Windows cmd进入指定目录全攻略:cd命令、跨盘符与批处理技巧

Windows cmd进入指定目录全攻略:cd命令、跨盘符与批处理技巧

Windows 下在 cmd 里进指定目录&#xff0c;这事看起来简单到不值一提&#xff0c;但实际操作中我见过太多人在这一步卡住——输入cd D:\某文件夹没反应&#xff0c;路径一长就报错&#xff0c;带空格的目录怎么都进不去&#xff0c;还有一个很经典的cd后提示「不是内部或外部命…

2026/10/20 20:58:45 阅读更多 →
LMDeploy 大模型部署实战:从模型量化到API服务全流程指南

LMDeploy 大模型部署实战:从模型量化到API服务全流程指南

之前帮某开发者的“模拟项目X”做大模型部署时&#xff0c;我在 GPU 服务器上对比过好几套推理方案&#xff0c;踩完一圈坑之后&#xff0c;现在手里的长期方案基本固定成了 LMDeploy。如果你手里已经有一个开源对话模型&#xff0c;正打算放进业务里做 API 服务&#xff0c;或…

2026/10/20 20:58:45 阅读更多 →
TensorFlow鞋类识别实战:Fashion MNIST图像分类全流程

TensorFlow鞋类识别实战:Fashion MNIST图像分类全流程

前段时间重新整理之前的深度学习实验笔记&#xff0c;翻到鞋类识别&#xff08;Fashion MNIST&#xff09;这个项目时&#xff0c;觉得特别值得拿出来单独写一篇。原因很简单&#xff1a;很多人入门深度学习时&#xff0c;都会被建议先跑通手写数字识别&#xff08;MNIST&#…

2026/10/20 20:57:37 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →