详解

不开启Revit,读取、写入Revit文件

要点:需要引入RevitNET.dll,RevitAddInUtility.dll和RevitAPI.dll三个dll到项目中

RevitAddInUtility.dll

此dll是Autodesk Revit 提供,用于方便开发者进行安装包的制作。使用此dll无需读注册表,可针对Revit版本,安装位置等信息的获取,也可以轻松的操控AddIn插件注册文件。此dll具体chm帮助文档,与此dll统一存在于Revit安装目录下。

RevitNET.dll

RevitNET.dll 在Revit安装目录下即可找到。此dll是Autodesk 用于开启一个简易版本 、无任何UI界面的小型化 Revit 所进行封装的。也就是使用此dll可做到无需启动Revit便可进行创建、修改、读取等等操作。并且因为是无界面操作,其效率要比Revit更高。其具体使用方法,如下代码所示。Navsiworks 即是使用了此dll。感兴趣的朋友可以进行尝试研究。

     public class Program{static readonly string WorkPath = Path.GetDirectoryName(typeof(Program).Assembly.Location);static Program(){RevitCoreContext.Instance.Run();}/// <summary>/// Revit 内核必须加 STAThread 标签/// </summary>/// <param name="args"></param>[STAThread]static void Main(string[] args){var app = RevitCoreContext.Instance.Application;// Todo ...var projectrTemplate = app.DefaultProjectTemplate;if (!File.Exists(projectrTemplate)){throw new FileNotFoundException("默认项目路径不存在 , 请指定 !");}var document = app.NewProjectDocument(projectrTemplate);if (document == null){throw new InvalidOperationException();}// create wall demo ...var p1 = XYZ.Zero;var p2 = p1 + XYZ.BasisX * 10;var p3 = p2 + XYZ.BasisY * 10;var p4 = p1 + XYZ.BasisY * 10;var points = new XYZ[] { p1, p2, p3, p4 };document.Invoke(m =>{var level0 = document.QueryByType<Level>().OfType<Level>().FirstOrDefault(x => Math.Abs(x.Elevation - 0.0) <= 1e-7);if (level0 == null){level0 = Level.Create(document, 0);document.Regenerate();}for (int i = 0; i < points.Length; i++){var a = points[i];var b = i == points.Length - 1 ? points[0] : points[i + 1];Wall.Create(document, Line.CreateBound(a, b), level0.Id, false);}});document.SaveAs(Path.Combine(WorkPath, "demowall.rvt"));RevitCoreContext.Instance.Stop();}}
     public class RevitCoreContext{// 此路径为动态反射搜索路径 、 此路径可为任意路径(只要路径下有RevitNET 所需依赖项即可,完整依赖项可在 Naviswork 2016 下面找到)static readonly string[] Searchs = RevitProductUtility.GetAllInstalledRevitProducts().Select(x => x.InstallLocation).ToArray();static readonly object lockobj = new object();static RevitCoreContext _instance;private Product _product;public Application Application { get => _product.Application; }public static RevitCoreContext Instance{get{if (_instance == null){lock (lockobj){if (_instance == null){_instance = new RevitCoreContext();}}}return _instance;}}static RevitCoreContext(){AddEnvironmentPaths(Searchs);AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;}public void Run(){_product = Product.GetInstalledProduct();var clientId = new ClientApplicationId(Guid.NewGuid(), "DotNet", "BIMAPI");// I am authorized by Autodesk to use this UI-less functionality. 必须是此字符串。 Autodesk 规定的._product.Init(clientId, "I am authorized by Autodesk to use this UI-less functionality.");}public void Stop(){_product?.Exit();}static void AddEnvironmentPaths(params string[] paths){var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };var newPath = string.Join(System.IO.Path.PathSeparator.ToString(), path.Concat(paths));Environment.SetEnvironmentVariable("PATH", newPath);}private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args){var assemblyName = new AssemblyName(args.Name);foreach (var item in Searchs){var file = string.Format("{0}.dll", System.IO.Path.Combine(item, assemblyName.Name));if (File.Exists(file)){return Assembly.LoadFile(file);}}return args.RequestingAssembly;}}
 public static class DocumentExtension{public static void Invoke(this Document doc, Action<Transaction> action, string name = "default"){using (var tr = new Transaction(doc, name)){tr.Start();action(tr);var status = tr.GetStatus();switch (status){case TransactionStatus.Started:tr.Commit();return;case TransactionStatus.Committed:case TransactionStatus.RolledBack:return;case TransactionStatus.Error:tr.RollBack();return;default:return;}}}public static TResult Invoke<TResult>(this Document doc, Func<Transaction, TResult> func, string name = "default"){using (var tr = new Transaction(doc, name)){tr.Start();var result = func(tr);var status = tr.GetStatus();switch (status){case TransactionStatus.Started:tr.Commit();return result;case TransactionStatus.Committed:case TransactionStatus.RolledBack:return result;case TransactionStatus.Error:tr.RollBack();return result;default:return result;}}}public static void InvokeSub(this Document doc, Action<SubTransaction> action){using (var tr = new SubTransaction(doc)){tr.Start();action(tr);var status = tr.GetStatus();switch (status){case TransactionStatus.Started:tr.Commit();return;case TransactionStatus.Committed:case TransactionStatus.RolledBack:break;case TransactionStatus.Error:tr.RollBack();return;default:return;}}}public static TResult InvokeSub<TResult>(this Document doc, Func<SubTransaction, TResult> func){using (var tr = new SubTransaction(doc)){tr.Start();var result = func(tr);var status = tr.GetStatus();switch (status){case TransactionStatus.Started:tr.Commit();return result;case TransactionStatus.Committed:case TransactionStatus.RolledBack:return result;case TransactionStatus.Error:tr.RollBack();return result;default:return result;}}}public static void InvokeGroup(this Document doc, Action<TransactionGroup> action, string name = "default"){using (var tr = new TransactionGroup(doc, name)){tr.Start();action(tr);var status = tr.GetStatus();switch (status){case TransactionStatus.Started:tr.Commit();return;case TransactionStatus.Committed:case TransactionStatus.RolledBack:break;case TransactionStatus.Error:tr.RollBack();return;default:return;}}}public static TResult InvokeGroup<TResult>(this Document doc, Func<TransactionGroup, TResult> func, string name = "default"){using (var tr = new TransactionGroup(doc, name)){tr.Start();var result = func(tr);var status = tr.GetStatus();switch (status){case TransactionStatus.Started:tr.Commit();return result;case TransactionStatus.Committed:case TransactionStatus.RolledBack:return result;case TransactionStatus.Error:tr.RollBack();return result;default:return result;}}}public static FilteredElementCollector QueryByType<T>(this Document doc) where T : Element{return new FilteredElementCollector(doc).OfClass(typeof(T));}}

问题总结

1,异常:SEHException: 外部组件发生异常

解决方法:Revit 内核必须加 STAThread 标签
RevitCoreContext.Instance.Run();

2,在Windows应用程序提示无法加载RevitNET.dll。

可能的原因是:目标平台为Any CPU,首先32位。
应该取消首先32位的对勾,或者更改为X64 。
目标框架注意与引用的项目一致(主要针对其它dll)

3,如何跨线程访问吗?

将RevitNet封装为一个控制台应用程序(Revit启动程序),然后通过命令行去启动Revit启动程序。
在启动过程可以传入参数。

Process process=new Process();//AppDomain.CurrentDomain.BaseDirectory +
process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory ,"ExportStart.exe");//执行的exe路径
process.StartInfo.UseShellExecute = false;//不显示shell
process.StartInfo.CreateNoWindow = true;//不创建窗口
process.StartInfo.RedirectStandardInput = true;//打开流输入
process.StartInfo.RedirectStandardOutput = true;//打开流输出
process.StartInfo.RedirectStandardError = true;//打开错误流
process.StartInfo.Arguments = "" + revitCmd + " \"" + filePathList.First() + "\"";//输入参数,多个参数使用空间分割,如果一个参数包含空格,使用""包括此参数
process.Start();//执行
string msg = process.StandardOutput.ReadToEnd();//读取输出
process.WaitForExit();//等待执行完成
process.Close();//结束

4,未能加载由“RevitNET.dll”导入的过程?


解决办法:
查看环境变量,将RevitInstallPath的path放至第一位。

5,不启动获取Revit文件的版本

     /// <summary>/// 获取Revit文件的版本/// </summary>/// <param name="path">文件路径</param>/// <returns></returns>public static string GetRevitVision(string path){string revitVision = null;FileStream stream = new FileStream(path, FileMode.Open);int size = 1024 * 1024;byte[] bytes = new byte[size];       while (stream.Read(bytes, 0, size) > 0){string str = Encoding.Unicode.GetString(bytes);string pattern = @"Autodesk Revit \d{4}";var match = Regex.Match(str, pattern);if (match.Success){revitVision = match.Value.Substring(match.Length - 4, 4);//File.WriteAllText(@"D:\abc.txt", str);break;}}return revitVision;}

6,程序运行目录(OutputDll)能否删除RevitAPI.dll或RevitAPIUI.dll等相关dll

可以,设置环境变量后,Revit会去Revit安装目录下查找以上dll。
注意:如果如果程序运行目录(OutputDll)存在Revit相关的dll,版本必须正确,否则会报错。(如果不能保证版本正确,不如将Revit相关dll全部删除)

7,RevitNet启动程序,能否取消RevitAddInUtility.dll的引用?

可以取消,RevitAddInUtility.dll 此dll的作用是用于获取Revit的安装目录,可以手动指定Revit的安装目录。从而取消此dll的引用。(完全可以不安装Revit,只复制Revit需要的dll,但区别那些dll是Revit需要的会很麻烦。不过可以将Revit安装目录下的文件全部复制到指定位置)

Revit二次开发——独立进程内读取、写入Revit文件相关推荐

  1. Revit二次开发01——环境搭建(附Revit 2018 + Visual Studio 2017下载地址)

    目录 1.准备工作 1.1 安装Revit 2018 1.2 安装Revit 2018 SDK 1.3 安装Visual Studio 2017 2.配置Addin Manager 3.测试 3.1 ...

  2. Revit二次开发之获取当前电脑所有Revit版本

    一.背景 小伙伴们在做Revit插件安装包时,是否需要获取当前电脑已经安装了哪些版本的Revit呢? 二.解决思路 主要有两种思路 通过注册表 通过revit提供的方式 这里推荐第2种方式,因为这种方 ...

  3. Revit二次开发之通过命令ID调用Revit自有命令

    参考一: PostableCommand Enumeration 参考二: 修改----ID_BUTTON_SELECT----MD----创建->选择;插入->选择;注释->选择; ...

  4. Revit二次开发——三角面创建

    Revit二次开发--三角面创建 文章目录 Revit二次开发--三角面创建 前言 一.三角面是什么? 二.三角网 三.使用步骤 1.引入库 2.开启事务 3.创建 总结 前言 三角面是创建实体的基础 ...

  5. 关于Revit二次开发的些许事

    关于Revit二次开发的些许事 关于Revit二次开发的些许事 Revit二次开发方向 岗位需求 哪些公司在招聘Revit研发岗位? 招聘的普遍岗位职责是什么? 岗位要求有哪些? 待遇是不是美丽?! ...

  6. Revit二次开发从入门到精通学习之路, (含Revit二次开发教程下载)

    Revit二次开发从入门到精通学习之路 Autodesk Joe Ye叶雄进 2. 18 2014    yexiongjin@hotmail.com Revit在国内的应用越来越广泛, Revit ...

  7. 再谈Revit二次开发的可靠性和前景

    接到一个问题咨询如下信息. Revit本身的开发规范吗?Revit发展前景如何?听说了一些Revit的身世,老担心它本身的代码就不规整.严谨,程序不够稳定,在这个平台上开始大规模二次开发有很大风险.公 ...

  8. Revit二次开发笔记

    Revit二次开发笔记: 配置:以revit 2021为例 Visual studio中的配置 以下是如果要翻成EnergyPlus模型需要的配置 如何安装Addin Manger和lookup插件 ...

  9. Revit二次开发加载RevitLookup.dll程序集

    Revit二次开发加载RevitLookup.dll程序集 Revit二次开发环境搭建(Revit 2019+Visual Studio 2017) 更正加载RevitLookup.dll: 编译出R ...

最新文章

  1. 百万数据报表导出:需求以及思路分析
  2. 内核 读写 flash mtd_2D动作卷轴《Lost Epic》公布 少女外表魂系内核|游民星空
  3. junit 预期错误_谨慎使用JUnit的预期异常
  4. 机箱硬盘指示灯不亮_安钛克DF600 FLUX机箱:FLUX平台第一款机箱,为全民电竞热“降温”...
  5. 舞动的桥 阿里云首个百万IOPS云盘的背后
  6. android 编译c代码吗,在Android手机上编译C代码
  7. java读取tif文件_java读取TIF,TIFF文件方法
  8. python语义分析_Python自然语言分析
  9. 高级气泡图——R语言简单实现
  10. 使用Certbot为nginx配置免费的https证书
  11. 微信、公总号、企业微信开发
  12. tomcat--catalina
  13. Vue-pdf实现在线预览PDF文件
  14. 百度云盘群组下载,细节操作让你摸不着头脑?
  15. 第四章 开始Unity Shader学习之旅(1)
  16. 中小企业网管管理完全篇 [转]
  17. 复现实验:文本数据的分类与分析
  18. 【BIM+GIS】ArcGIS Pro2.8如何打开Revit模型,BIM和GIS融合?
  19. 如何生成小程序太阳码
  20. 高一物理借助传感器用计算机测速度,【2-2讲义·习题】第4节 实验:用打点计时器测速度...

热门文章

  1. 单目图像深度估计 - 迁移篇:Depth Extraction from Video Using Non-parametric Sampling
  2. 让我们一起开发【菜谱系统】吧,滚雪球学 Python 第三轮项目计划
  3. USB Full-Speed 控制传输
  4. 有赞 java_响应式架构与 RxJava 在有赞零售的实践
  5. 抢红包代码 php,ASP.NET代码轻松实现微信抢红包
  6. 计算机n位数的表示范围,计算机组成原理——原码、反码、补码的表示范围
  7. 【随笔】AI+眼镜行业
  8. 猎聘Q1营收毛利齐增,在线招聘的“春天”要来了么?
  9. Barcode读取之barcode_para_contrast_min.hdev
  10. 守株待兔都赚钱了,几十个IP怎么比几万IP还赚钱