ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RevitLookup 2020实战:编译、注册与排坑全解析

RevitLookup 2020实战:编译、注册与排坑全解析 简介RevitLookup 2020 是一款面向 Revit 二次开发者的表格查找工具核心价值在于快速查看元素属性、参数、几何及内部数据结构避免在插件调试中反复编写临时输出代码是 Revit 开发过程中定位问题的实用组件。压缩包共 161 个文件以 78 个 C# 源码文件为主干配合 resources/resx 资源文件、bmp/ico 界面图标、addin 插件配置、dll 程序集以及 pdb 调试符号另有 sln/csproj 工程文件和 doc/txt 说明文档整体仅 1.05MB结构清晰便于按需检索。部署方式灵活既可直接将 RevitLookup.addin 与 RevitLookup.dll 放入 Revit Addins 目录使用也可用 Visual Studio 打开源码修正引用路径后重新编译生成 dll适配不同 Revit 环境。平台已有 1652 人学习下载。包含完整工程与配套文档适合初中级 Revit 开发者对照源码理解元素结构也可作为二次开发的基础框架在此基础上扩展自定义查询或界面功能。1. RevitLookup 2020能做什么先在“看不见的参数”里找回自信做Revit二次开发的人迟早会撞上同一个尴尬时刻你用API读一个墙的体积读出来是0或者是一个莫名其妙的极小值你翻遍了官方文档也没找到这个元素的内部结构。这时候你需要的不是console.log而是一个能钻进Revit进程、把每一个对象扒开看的工具。RevitLookup 2020正是干这个的。它本质上是Revit API的“挖地三尺”查看器选中任意图元双击就能看到它的类名、所有参数、几何体、材质、与其它元素的连接关系。它不适合给业主做汇报但它能让开发者省下几个通宵。这篇文章从源码和addin说起把RevitLookup 2020的编译、注册、使用和踩坑一次讲透。适合正在做Revit插件、被API细节磨到头皮发麻的开发者也适合想用现成工具搞懂Revit内部数据结构的技术负责人。2. 为什么RevitLookup要设计成addin从加载机制看它的边界2.1 Revit插件的入口addin文件不是摆设Revit不像普通Windows程序双击exe就能跑。它有一套自己的扩展机制所有外部功能必须通过一个*.addin文件告诉Revit“这里有我的工具”。这个XML格式的清单文件指向真正干活的dll程序集。RevitLookup 2020也不例外它的文件夹里一定有一个RevitLookup.addin你在源码里找不到它时反而说明你手里的包不完整。addin文件里最关键的不是Assembly节点而是AddInType——它区分你是“应用级”还是“命令级”。RevitLookup需要主动往Revit面板里塞按钮所以它是Application级。如果写错成CommandRevit会直接忽略整个文件这是最低级的坑后面会细说。2.2 RevitLookup如何拿到你的元素与属性反射与实现接口拿到addin之后Revit会调用你的类这个类必须实现IExternalApplication接口并在OnStartup里注册一个可以触发查询界面的按钮。但RevitLookup真正厉害的地方是——它不直接知道你要查什么而是利用.NET反射机制在运行时遍历目标对象的公开属性、字段和方法。你选中一个Wall它就把Wall对象的基类Element的全部属性列出来连InternalGeometry这种隐藏的心跳数据都不放过。这种设计思路有一个明显好处Revit升级时API类变化只要反射还在工具就能跟着兼容。所以RevitLookup 2020虽然是为Revit 2020编译的但很多代码可以直接被新版本复用。缺点是反射有性能开销用在高频刷新上会卡这决定了它更多是“定点检查”而不是“持续监控”。2.3 源码包里最值得先读的两个文件拿到源码包后不要急着找sln。先打开RevitLookup/App.cs看它是如何初始化面板按钮和绑定查找器的。这里藏着从ExternalApplication到RevitLookupViewModel的完整链路。第二个要读的是Snoop/Forms/下的主窗口实现它负责把反射到的数据塞进TreeView。如果你要模仿它做同类工具这两个文件就是最好的模板。源码里还有一个容易被忽略的docs文件夹里面经常有作者整理的浏览器导航说明虽然没人细看但遇到界面空白时它可能是唯一能救你的线索。3. 用源码编译RevitLookup 2020从sln到可用插件的完整路径3.1 编译环境的三大预备SDK、程序集引用与目标框架RevitLookup是C#和WPF写的运行环境在Revit 2020进程内必然依赖.NET Framework。默认项目目标框架通常是net472或net48你必须在编译时确认本机装了对应的.NET Framework Developer Pack否则Visual Studio所有项目头都会标黄。第二步是引用Revit API程序集。注意直接复制RevitAPI.dll到项目目录是懒人做法我一般通过Reference Path直接指向Revit安装目录这样防止多个Revit版本时引用混乱。第三步新版RevitLookup还会用到PresentationCore和WindowsBase等WPF程序集这些不需要手动找项目自带的packages.config或csproj文件里都写明了。最容易被忽视的是需要勾选“Allow unsafe code”反射某些几何对象时要用到unsafe指针不打开会编译失败。3.2 用MSBuild在命令行完成Release编译拿到源码后在Windows命令行里进入源码根目录执行msbuild RevitLookup.sln /p:ConfigurationRelease /p:Platformx64 /m参数说明/p:ConfigurationRelease指定编译发布版避开调试版里大量Debug断言/p:Platformx64是因为Revit 2020完全64位任何AnyCPU目标都可能在运行时被强制拒载/m开启多核编译节省时间。如果MSBuild报告无法解析项目多半是Visual Studio没装“使用C的桌面开发”或“.NET桌面开发”工作负载这也直接导致系统找不到Microsoft.Cpp相关targets。你不需要命令行高手但这条命令比在VS里点半天更直白编译日志里能看到每一处引用的程序集来自哪里。3.3 没有Visual Studio时用dotnet build的替代方案如果你电脑上只有.NET Core SDK能不能编译这里有个老司机的坑dotnet build默认定位SDK风格项目而RevitLookup这类老项目多数是传统的非SDK风格csproj。硬用dotnet build会得到“当前项目不是SDK项目”的错误。但我试过的可行做法是先手动创建一个RevitLookup.sln对应的Directory.Build.props文件把TargetFramework统一写死再执行dotnet build RevitLookup.csproj -c Release不过前提是装了.NET Framework 4.7.2以上引用程序集否则dotnet build连System.Windows.Forms都找不到。务实建议装一个免费的Visual Studio Community选Workload时只勾“.NET 桌面开发”和“MSBuild”两个组件比折腾命令行省时间。但在无UI的CI上dotnet build也是能用的上面这个trick给我省过一次机器环境问题。4. 注册addin到Revit 2020并验证加载两种落地方案4.1 全局addin存放位置与XML字段逐个说明把编译出来的RevitLookup.dll和它的依赖放同一个目录然后写一个加载清单。全局方案是把addin文件丢进C:\ProgramData\Autodesk\Revit\Addins\2020\这个路径对所有用户生效适合公司统一部署。我的addin文件内容如下?xml version1.0 encodingutf-8? AddIn TypeApplication NameRevitLookup 2020/Name AssemblyD:\Tools\RevitLookup\RevitLookup.dll/Assembly FullClassNameRevitLookup.App/FullClassName AddInId47A1E8A0-2A1C-4C3C-8C1A-6B3B7B8A1C01/AddInId VendorIdRevitLookup/VendorId VendorDescriptionOpen-source element inspector/VendorDescription /AddIn这里参数说明TypeApplication告诉Revit这是一个应用级插件会在启动时执行Assembly路径必须是绝对路径用相对路径会在一小时后随机失败这是老WinForms血泪经验FullClassName要写带命名空间的类名不是文件名AddInId必须是GUID字符串你可以手动生成一个但不要和别的插件重复否则Revit只加载其中一个而且不报错。4.2 用户级addin方案不需要管理员权限的注册方式没有管理员权限的公司电脑全局ProgramData写不进去所以Revit也会扫描用户级目录C:\ProgramData\Autodesk\Revit\Addins\2020\是全局C:\Users\用户名\AppData\Roaming\Autodesk\Revit\Addins\2020\是当前用户。只要把同一个.addin文件复制到用户目录重启Revit即可。这个方案的坑在于Revit的版本目录可能带2020和2020.1两个细分目录而实际加载的是后者。你判断是否生效直接看“附加模块”选项卡下是否多了一个“RevitLookup”按钮这个按钮通常和一个“Snoop Current Selection”下拉菜单在一起。如果没出现先关闭Revit检查Windows事件查看器里是否有加载错误而不是反复删除addin文件做无用功。4.3 加载成功的可观察迹象启动Revit 2020打开任意项目在“附加模块”里看到“RevitLookup”基本就成功了。但注意插件启动时如果有弹窗报Assembly load failure多半是依赖的DLL不在同一目录或者引用的Revit API版本不是2020。另一个容易被误认为失败的现象是——点击按钮后没有任何窗口弹出但Windows任务管理器里多了RevitLookup.exe进程不对它应该在Revit进程内不会出现额外进程。正确验证方式是选中一面墙点击“Snoop Current Selection”此时弹出窗口左边是当前元素右边是属性树。如果树只显示一两个节点说明你的dll加载了但缺少关联功能最常见原因是RevitLookup的版本与主程序不匹配。5. RevitLookup 2020不干活五个高频踩坑与排查5.1 addin写对了Revit却无视它现象addin文件放在了正确目录重启Revit两次仍然看不到“RevitLookup”按钮。原因多数不是内容错误而是文件名大小写或扩展名问题Windows默认不显示扩展名你看着文件是.addin实际可能是.addin.txt。解决在cmd里执行dir C:\ProgramData\Autodesk\Revit\Addins\2020\看真实文件名如果是.addin.txt直接改名。其次是检查XML标签是不是写成小写addinRevit的解析器区分大小写必须首字母大写。5.2 编译成功后加载闪退现象点击“Snoop Current Selection”后Revit直接崩溃且错误事件里报System.BadImageFormatException。原因你的DLL编译目标是x86或AnyCPU而Revit 2020是64位进程混合模式加载时无法解析。解决回Visual Studio把项目平台改为x64并检查所有引用了的NuGet包是否也是64位兼容。另外某些老版本的RevitLookup在Release模式下未启用“优化代码”导致大量JSON序列化库生成临时程序集闪退更频繁编译时建议勾选“项目属性-生成-优化代码”。5.3 打开工具却是一片空白现象窗口能打开但左侧元素树是空的点击“Snoop”没有内容。原因你选中了一个在Revit内部已经失效的元素比如被其他事务删掉了或者当前处于“编辑族”模式外部文档上下文不可用。解决先点击Revit“管理”标签下的“重新载入”或切换到一个3D视图重新选择实心几何。还有一个高频场景在“项目浏览器”里选中一个视图而不是元素RevitLookup不会为你展示视图对象。确认左侧是灰色且有“Element”字样才是真正选中了可查元素。5.4 查询数据与Revit界面不一致现象你用RevitLookup读到的Volume参数和Revit的“属性面板”里显示的数值不同怀疑插件是假的。原因单位换算。Revit内部存储数据都是英尺公共参数Volume返回double类型而界面显示时自动换算成立方米。RevitLookup默认展示原始值并没有做单位格式化。解决查看数值时要看值旁边是否标注了“feet³”或查阅API的DisplayUnitType说明。如果你要用它验证自己的API代码建议在代码里调用UnitUtils.ConvertFromInternalUnits再比较而不是拿一眼黑的数据线直接对。5.5 关于性能用错对象导致卡死的案例现象选中一个复杂RVT模型里的百万图元模型组点击Snoop后Revit卡了十几秒甚至内存飙升到4G。原因RevitLookup会反射展开该对象的所有属性而某些几何对象包含大量三角面片数据它会一次性全部读取并放进树节点。解决不要直接就点最上层的“对象详情”按钮先在左侧列表里找“Geometry”节点只展开你真正需要的那一项。如果你是插件作者建议给RevitLookup封装一个“防止递归查询”的扩展方法用[Browsable(false)]过滤掉那些体积大的集合。这不算bug但设计上它默认“全量展示”行为激进。6. 把它当作反向调试器让RevitLookup为你自己的API代码背书6.1 用“对比元素数据”定位不透明参数写API读参数时最怕户型里同一个参数名字在不同族里含义不同。我一般做法是先手动用RevitLookup选中元素把它的“参数列表”里每个BuiltInParameter枚举值拷贝出来再打开自己代码里用LookupParameter读取的结果做逐条比对。比如你发现代码里读ElementId数值是897而RevitLookup显示Id.Ref是897但外部读取会拿到897L问题就在类型转换。要让对比高效可以写一个简单的控制台脚本把RevitLookup导出的JSON和你的API日志合并每一条不一致都打印出来。// 用RevitLookup导出当前选中元素的参数表到JSON var paramData new Dictionarystring, string(); foreach (Parameter p in solidElement.Parameters) { paramData[p.Definition.Name] p.AsValueString(); } File.WriteAllText(dump.json, JsonConvert.SerializeObject(paramData));这里的参数说明AsValueString()返回显示值适合与界面比对如果要用到通用单位最好是改成AsDouble()并记录单位类型否则不同格式族会出现两个字面值但实际相同的情况。这段代码的价值在于把人工点鼠标和程序化读取统一到同一份数据源你验证一次之后就再也不用对着Revit自带的属性面板发呆。6.2 利用DockablePanel把RevitLookup嵌入你的面板熟悉Revit 2020 API的人知道有DockablePanel的机制但通常第一反应是“只能嵌系统提供的面板”。RevitLookup源码里有一个DockablePanel示例它演示了如何把一个自定义WPF控件注册到Revit界面右侧。你可以复用它的RegisterDockablePanel方法把自己公司的查询工具做成常驻面板不用每次点击“Snoop”。常见做法是声明一个唯一DockablePanelId并在OnStartup里调用RegisterDockablePanel。这里有一个需要注意的点面板注册的key必须全局唯一否则会在另一个装有RevitLookup的电脑上冲突导致面板空白。6.3 把源码里的“Snoop”入口迁移到自己的插件如果不想整体引入RevitLookup可以只抽出它的snoop文件夹里的几个核心类改造命名空间后复用。迁移时最省事的办法是粘贴其中的SnoopElement方法它接受一个Element参数返回树的根节点。我把这个方法封装成一个静态库然后在自己的外部Command里调用。结果就是我自己的插件界面里嵌入了一个“查看当前元素”按钮底层用的是RevitLookup的反射逻辑。这样做的好处是团队里其他人不用再去学独立的RevitLookup直接在插件里点一下就能查数据。但要注意许可证RevitLookup是MIT协议开源复制代码时保留版权声明别改成自己的名字。说回我的日常习惯。现在拿到任何不确定的Revit API对象我的第一反应不是马上写调试输出而是先问一句“RevitLookup能不能看到它”如果能80%的问题都能在迁移到代码前定位清楚。这个工具的价值不是替你写插件而是当你把未知变成已知以后再写代码就是顺水推舟的事。希望这篇笔记能让你少踩几个看上去很隐晦的坑更早把精力花在真正要解决的问题上。本文还有配套的精品资源点击获取
返回列表