☰
RevitLookup 2020:Revit二次开发必备的插件调试与部署指南
2026/10/20 16:23:09 网站建设 项目流程

简介:RevitLookup 2020是一款面向Revit二次开发的辅助查找工具,适合使用Revit 2020并需要查看内部对象数据的插件开发者。它可帮助快速查询元素、类别、参数、几何等底层信息,常用于调试插件、理解API对象结构。资源包内含完整C#源码与addin配置,便于学习Revit API调用方式和工具实现细节。整个压缩包共161个文件,仅1.05MB,主要包括78个cs源码文件、Visual Studio工程(sln/csproj)、可直接复制的RevitLookup.dll与addin文件,以及bmp、ico、resx等界面资源文件;目录组织清晰,既可直接放到Revit插件目录尝试使用,也适合用Visual Studio打开源码自行更新引用并重新编译。目前已有1654人学习下载,对于正在做Revit二次开发、希望提升调试效率的开发者来说,是一份轻量且实用的参考工具。

1. 用 RevitLookup 2020 拆开 Revit 元素的黑匣子:每个二次开发者的调试刚需

写 Revit 插件时最耗时间的不是写代码,而是猜某个元素内部到底存着什么。我调一个墙的类型参数,先写循环遍历 Parameters,再用长长的条件判断过滤内置参数名,最后还得靠 MessageBox 一行行弹出来看。RevitLookup 2020 改变了这个流程:它是一个加载进 Revit 2020 的附加模块,选一个元素,点一下 Lookup,就能把墙、族、视图、尺寸标注、房间等对象的属性树完全展开——参数名、参数值、ElementId、几何引用、LocationCurve 全部呈现在你面前。这个工具源码和 addin 文件一起打包好了,拿到手可以直接编译、改、部署。适合刚接触 Revit 二次开发的人快速理解 API 结构,也适合老手在封装不熟悉的 API 对象前做现场勘察,省掉“先写一大段测试代码再猜”的时间。

2. 编译 RevitLookup 2020 源码:从解决方案到三个关键编译开关

RevitLookup 与 Revit 版本强绑定,这份源码标明 2020,就是对着 Revit 2020 的 API 程序集写的。想用在 2021 或更高版本上,得改引用替换源码,不是直接能跑。下面先解决如何把它编译成可加载的 DLL。

2.1 事前准备:先把版本和环境对齐

开发环境按常见配置来:Windows 10 或 Windows 11,装上 Visual Studio 2019 或 2022,工作负载里勾选“.NET 桌面开发”。Revit 2020 本身是 64 位进程,所以编译目标平台要么选 x64,要么选 AnyCPU,但千万别选 x86。

源码包解压后,目录里一般能看到的文件包括:

文件作用
RevitLookup.sln解决方案入口,用 VS 直接打开
RevitLookup.csproj项目文件,里面放着引用路径和编译配置
RevitLookup.addin插件清单,Revit 启动时靠它找到 DLL
App.csIExternalApplication 入口,负责挂载 Ribbon 按钮
Snoop*.cs核心逻辑,负责展开对象结构

编译前要确认 RevitAPI.dll 引用指向正确的 Revit 2020 安装目录。很多翻车都是因为电脑上装了多个 Revit 版本,csproj 里的 HintPath 写着 2021 的路径,编译能过,加载时却各种报错。引用建议这样配:

<Reference Include="RevitAPI"> <HintPath>D:\Revit2020\Public Assemblies\RevitAPI.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="RevitAPIUI"> <HintPath>D:\Revit2020\Public Assemblies\RevitAPIUI.dll</HintPath> <Private>False</Private> </Reference>

逻辑说明:如果 Revit 安装在 C 盘默认位置,把路径改成对应安装目录下 Public Assemblies 文件夹的绝对地址。 设为 False 很关键——它告诉编译器不要把这几个 Revit 程序集复制到输出目录,运行时由 Revit 主进程提供。如果你把 Private 设为 True,输出的 bin 文件夹里会多出几个 Revit 的 DLL 副本,反而容易引发版本冲突。

参数说明:HintPath 是 csproj 里相对常见且稳定的引用写法;当 HintPath 指向的文件不存在时,VS 会显示黄色警告并在引用节点上标感叹号。遇到这种情况,把引用删掉重新添加,指向 Revit 2020 的 Public Assemblies,警告即消。

2.2 编译步骤:可视化与命令行两条路

最简单的做法是双击 RevitLookup.sln,等待 VS 完成加载和 NuGet 还原,然后在解决方案上右键,选择“生成解决方案”。输出路径通常是项目目录下的 bin\Release 或 bin\Debug,取决于当前配置。

如果不想开 GUI,也可以用命令行编译。以管理员身份打开“开发者命令提示符”,进入源码目录:

cd D:\RevitLookup-2020 nuget restore RevitLookup.sln MSBuild.exe RevitLookup.sln /p:Configuration=Release /p:Platform=x64

逻辑说明:nuget restore 是为了拉取解决方案引用的第三方包。RevitLookup 本身依赖很少,很多版本甚至没有 NuGet 包,但顺手执行一遍没有副作用。MSBuild 是 VS 背后的编译引擎,不启动 IDE 也能出 DLL。

参数说明:Configuration=Release 让输出更干净,Debug 也没问题,只是加载后调试符号稍微多些。Platform=x64 直接产出一个 64 位程序集,规避了 AnyCPU 在不同进程环境下被意外加载成 32 位的可能。如果你在 VS 里编译,记得在“配置管理器”里确认活动解决方案平台是 x64 或 AnyCPU。

2.3 生成产物:DLL、addin、PDB 各司其职

编译成功后,打开 bin\Release 文件夹,能看到几个关键文件:

文件作用是否必须部署
RevitLookup.dll主程序集,所有功能都在里面必须
RevitLookup.addinXML 清单,告诉 Revit 加载哪个类、哪套 DLL必须
RevitLookup.pdb调试符号,崩溃时能定位到具体行号建议保留
其他 .dll第三方依赖有就一起带上

这里有个常见误解:有人以为 addin 文件是 Revit 自动生成的,不需要管。实际上 Revit 2020 的插件加载机制是靠 addin 清单文件的,它不会扫描任意目录里的 DLL,只会读指定的 Web 服务目录和本地 AddIns 文件夹。addin 文件里写的 DLL 路径,就是最终被加载的路径。

我一般会先在编译目录里检查一遍 addin 文件是否存在。如果源码包里没带,也没关系,下一章直接手写一个,比改现成的还快。这一步的核心目的只有一个:把 DLL 和 addin 的关系理顺,后面部署才不会懵。

3. 部署与加载:addin 文件的 XML 结构和存放位置决定成败

编译成功只是第一步,Revit 认不认这个插件,完全看 addin 清单内容和你把文件放到了哪个目录。这一章把这两件事拆开讲。

3.1 addin 文件三个关键节点:Type、Assembly、FullClassName

以最常见的 Application 型清单为例,一个能用的 RevitLookup.addin 内容长这样:

<?xml version="1.0" encoding="utf-8"?> <RevitAddIns> <AddIn Type="Application"> <Name>RevitLookup 2020</Name> <Assembly>D:\RevitLookup-2020\bin\Release\RevitLookup.dll</Assembly> <FullClassName>RevitLookup.App</FullClassName> <AddInId>4F2D1B8A-7C3E-4E6B-9D44-5A1B2C3D4E5F</AddInId> </AddIn> </RevitAddIns>

逐节点说明:Type="Application" 表示插件是一个外部应用,Revit 启动时就要加载,用于往 Ribbon 上加按钮;如果插件是命令,Type 要改成 Command,FullClassName 也要换成实现了 IExternalCommand 的类。RevitLookup 需要把 Lookup 按钮挂到界面面板上,所以必须走 Application 身份。

Assembly 节点写的是 DLL 的绝对路径。有人写成相对路径,结果不同机器上路径解析不一致,加载失败。我建议一律写绝对路径,顶多是换电脑后改一下。

FullClassName 是程序集中入口类的完全限定名,一定带命名空间。比如源码里入口类是 App,在 RevitLookup 命名空间下,FullClassName 就是 RevitLookup.App。写错一个字母,Revit 会提示找不到类型。

AddInId 是插件唯一标识,标准 GUID 格式。它不需要和 DLL 内部注册的东西一致,但必须保证同一个加载环境下不跟其他插件重复。生成方法很简单:Visual Studio 菜单里的“工具 → 创建 GUID”,选带连字符的格式,粘贴进来就行。

3.2 存放位置:两个 AddIns 目录和它们的优先级

Revit 2020 的插件目录是按年份命名的,和 Revit 2019、2021 的目录分开。常见的两个位置是:

目录作用
C:\ProgramData\Revit\Addins\2020\所有 Windows 用户共享,适合团队统一部署
C:\Users\你的用户名\AppData\Roaming\Revit\Addins\2020\仅当前用户可见,适合个人调试

注意,这两条路径在不同中文系统上可能显示为“ProgramData”或“用户”等本地化名称,但目录结构一致。

放置原则:单人开发放 AppData 下即可;要给多个同事分发,放 ProgramData 更合适。若两份目录同时存在同名 addin,Revit 默认优先读取 ProgramData 下的配置,调试时先确认你改的是不是生效的那一份。

另外,别把 addin 文件直接放在 Revit 安装目录的 Program 文件夹里,那不会生效。Revit 只扫描上述两个指定的 AddIns 文件夹,其他位置一概不认。

3.3 验证加载结果:从“附加模块”选项卡看真相

把 DLL 和 addin 都放好之后,启动 Revit 2020,切换到“附加模块”选项卡,正常情况下会出现名为 LookUp 的面板或按钮。

点击按钮前先选中一个元素,再点 Lookup,窗口会弹出并展开该元素的对象树。如果按钮出现了但点完没反应,最常见的原因是当前选择的元素类型不支持 Lookup 展开,比如选中的是视口外空白区域。还有一种验证方法:在“附加模块”选项卡下,找到“外部工具”下的各类命令入口,如果这里的列表也没有 RevitLookup,说明清单没有被 Revit 识别。

到这里,插件已经能用了。接下来整理几个我实际踩过、也帮同事排查过的坑。

4. 避坑排查:RevitLookup 2020 最常见的五个加载与运行问题

越基础的工具,越容易在加载环节出幺蛾子。下面这五条按“现象 → 原因 → 解决”展开,都是实际环境中反复出现的。

4.1 加载阶段的三个高频问题

现象一:附加模块选项卡上根本没有 LookUp 按钮。

原因:addin 文件没被 Revit 扫描到,或者 XML 格式非法。很多情况下是下载的源码包里的 addin 文件编码有问题,或者 GUID 在被复制过程中丢了连字符。

解决:用记事本或 VS 打开 addin 文件,确认 XML 结构完整;把 AddInId 换成新生成的 GUID;最后确认文件确实放在 2020 这个年份目录下——我见过有人把 2020 的插件放进 2021 文件夹,症状一模一样。

现象二:启动 Revit 时弹“无法加载程序集 RevitLookup.dll”,应用直接退到编辑界面。

原因:Assembly 节点里的 DLL 路径失效,或者 DLL 引用的 .NET Framework 版本高于 Revit 2020 支持的版本。Revit 2020 默认跑在 .NET Framework 4.7 上,如果 csproj 把目标框架改成了 4.8 以上,加载时就会因运行时版本不匹配而罢工。

解决:先确认 Assembly 里的路径存在且文件名正确;再把项目目标框架改为 .NET Framework 4.7.2,重新编译,替换 DLL 后重试。这种现象在高版本 VS 新建项目时特别容易翻车,因为默认目标框架往往偏高。

现象三:点按钮毫无反应,也不报错。

原因:FullClassName 写错或加上了不存在的命名空间,导致 Revit 找不到入口类。这时 Revit 只会在日志里记录错误,界面不会有任何提示。

解决:打开 DLL 对应的源码,确认入口类名和命名空间,修改 addin 里的 FullClassName 后重启 Revit。还有一个笨但有效的办法:用任意 PE 工具打开 DLL,查看导出的类型列表,入口类一定在里面。

4.2 运行阶段的常见异常

现象四:Lookup 窗口能打开,但对象树内容为空,或者只有少部分参数。

原因:多数情况下,选中的是几何图元而不是有参数的元素,比如选了一个 SketchPlane 或 ImportInstance;也可能是元素参数本来就分为“实例参数”和“类型参数”两类,Lookup 默认展示的是实例参数,类型参数需要进一步展开 Type 节点。

解决:在 Lookup 窗口里点击元素对应的 Type 节点,看类型参数;如果是导入符号,先切换到族实例或系统族再看。这个操作逻辑其实和 Revit API 一致——Category、Parameter 和 ElementId 的基础数据都是按实例和类型分层的。

现象五:编译能过,但运行到一半崩溃,错误信息指向“版本冲突”。

原因:csproj 引用 RevitAPI 时 Private 设置为 True,编译器把 RevitAPI.dll 复制到了输出目录,同时 Revit 进程又加载了自己内部的同一份程序集,两边的程序集版本标识不一致,运行时类型传递失败。

解决:把引用里的 Private 改成 False,重新编译,删除 bin 下的旧 DLL 再部署一次。这个坑撑得上典型的“表面没问题,跑起来就炸”,排查时先看引用配置永远是对的。

5. 进阶用法:用 Lookup 反推 API 对象结构,而不是只看参数

很多人把 Lookup 当参数查看器用,这其实浪费了它最大的价值。它本质是一个“对象结构可视化器”,能从 UI 界面反推出 API 类型层次,配合少量测试代码,直接转化成你的业务逻辑。

5.1 从对象树映射到 C# 属性

拿墙举例。在 Lookup 里选中一面墙,展开根节点,能看到 LocationCurve,Width,BuildingType,StructuralUsage 等字段。这些字段名和 Revit API 里的属性几乎一一对应,我可以照着写代码:

Wall wall = doc.GetElement(new ElementId(...)) as Wall; if (wall != null) { Debug.Print("LocationCurve: {0}", wall.Location?.GetType().Name); Debug.Print("Width: {0}", wall.Width); ElementId typeId = wall.GetTypeId(); Debug.Print("WallType: {0}", doc.GetElement(typeId)?.Name); }

这段代码的逻辑是:先拿到当前选中的元素,转成 Wall 类型,再用 Lookup 里看到的属性名直接取值。注意 LocationCurve 在 Lookup 里显示为一条直线数据,但它的实际类型是 LocationCurve,而 wall.Location 的返回类型是 Location,需要通过 GetType().Name 才能确认是 LocationCurve 还是 LocationPoint。Lookup 的价值就在这——它能直接告诉你运行时类型到底是什么。

5.2 用搜索框快速定位嵌套参数

族实例、房间、标注这些元素常常嵌套很深:元件 → 类型 → 参数组 → 共享参数。手动展开得点好多次,效率很低。

Lookup 的窗口顶部一般带搜索框或类型筛选功能,我通常输入大概的参数名,比如输入“Height”,它能快速过滤出所有名字里带 Height 的字段和参数。定位到目标后,直接看它属于哪个父节点,就能知道这个参数到底挂在 Element 上、ElementType 上还是某个 GeometryObject 上。这个信息比查 API 文档还直接,因为它展示的是实际运行时的对象结构。

5.3 把 Lookup 结果变成你自己的调试日志模块

看懂结构之后,下一步是把它内化成自己的工具。我常写一个通用的参数导出函数,原理和 Lookup 展开参数列表一样,只是输出目标从窗口变成文本文件:

private void DumpElementParameters(Element element, string filePath) { var sb = new StringBuilder(); foreach (Parameter param in element.Parameters) { string val; switch (param.StorageType) { case StorageType.String: val = param.AsString(); break; case StorageType.Integer: val = param.AsInteger().ToString(); break; case StorageType.Double: val = param.AsDouble().ToString(); break; case StorageType.ElementId: val = param.AsElementId().ToString(); break; default: val = "<null>"; break; } sb.AppendLine($"{param.Definition.Name} = {val}"); } File.WriteAllText(filePath, sb.ToString()); }

逻辑说明:这个函数遍历元素的所有参数,把每个参数按存储类型转换成字符串,再拼接输出。它比 Lookup 多做的事是:把现场数据落地成文件,方便对比不同元素的参数差异,或者在批量处理日志里记录每次操作的上下文。

参数说明:StorageType 决定了怎么取值,这是 Revit API 里最容易忽略的细节。参数不是只有字符串一种存储方式,还有整数、浮点数和 ElementId,直接 AsString() 对某些 StoreageType 会返回空值。

写好这个工具函数后,再看 Lookup 时,它就成了我的“排错对照表”:界面里怎么看,代码里就怎么写,两者互为印证。

6. 让 Lookup 成为调试习惯:一个从对象结构直接生成日志的小技巧

从 Lookup 到自己的调试代码,其实只差一步:把看到的结构自动转化成日志文件。我的做法是在测试命令里加一个反射式的属性遍历函数,作用类似迷你版 Lookup。

public static void DumpProperties(object obj) { if (obj == null) return; foreach (PropertyInfo prop in obj.GetType().GetProperties()) { try { object value = prop.GetValue(obj, null); Debug.Print($"{prop.Name}: {value ?? "<null>"}"); } catch (Exception ex) { Debug.Print($"{prop.Name}: <error> {ex.Message}"); } } }

这个函数不针对某个具体的 Wall 或 FamilyInstance,而是对任意对象输出所有属性的值。调试的时候,在可疑对象的赋值点之后调用 DumpProperties,日志里立刻能看到哪个属性是 null、哪个抛异常,和 Lookup 窗口里的层级一一对应,排查效率高出一截。

从那以后,每次收到别人的插件代码或者接触没见过的 API 对象,我都强制自己先走一遍流程:启动 Revit 2020,选中目标元素,用 Lookup 展开看结构,再动手写代码;写完业务逻辑后,如果运行结果不对,不急着猜,先加一行 DumpProperties 看看对象状态。整套流程走下来,比翻文档、猜属性、盲写循环快多了。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询