本文章主要是使用C#对CAD进行开发时,需要用到的一些简单的、常规的方法介绍,仅供参考。

1、RealDwg辅助类:

public class HostServices : HostApplicationServices
{public override string FindFile(string fileName, Database database, FindFileHint hint){throw new NotImplementedException();}
}public class RealDwgHelper
{/// <summary>/// 创建新的Database/// </summary>/// <param name="dwgPath">dwg文件路径</param>/// <returns></returns>public static Database CreateNewDatabase(string dwgPath){// 初始化依赖环境Initialize();// 创建database实例Database db = new Database(false, true);if (dwgPath.ToLower().EndsWith("dwg")){db.ReadDwgFile(dwgPath, FileShare.ReadWrite, true, "");}else if (dwgPath.ToLower().EndsWith("dxf")){db.DxfIn(dwgPath, dwgPath + ".log");}else{Console.WriteLine("不支持的格式");}db.CloseInput(true);return db;}public static bool IsInitialized;public static void Initialize(){if (!IsInitialized){IsInitialized = true;// 初始化依赖环境InitHashTable();HostServices dwg = new HostServices();RuntimeSystem.Initialize(dwg, 1033);}}static public Hashtable mOverrides;///<summary>/// This initializes the hashtable with all the functions and properties which are overridden in the class./// It is using Reflection to achieve this./// </summary>static public void InitHashTable(){mOverrides = new Hashtable();Type t = typeof(HostServices);MethodInfo[] methods = t.GetMethods();foreach (MethodInfo method in methods){if (!mOverrides.Contains(method.Name) && method.DeclaringType == t)mOverrides.Add(method.Name, true);}}/// <summary>/// 创建新的Database/// </summary>/// <param name="dwgPath">dwg文件地址</param>/// <param name="needRecovery">是否需要修复文件,true需要修复</param>/// <returns>返回一个Database</returns>public static Database CreateNewDatabase(string dwgPath, bool needRecovery){string fileName = dwgPath;if (needRecovery){var newPath = Path.ChangeExtension(dwgPath, "recover.dwg");if (TextStyleRecovery(dwgPath, ref newPath)){fileName = newPath;}}return CreateNewDatabase(fileName);}/// <summary>/// 修复字体样式/// </summary>/// <param name="fileName">dwg文件地址</param>/// <param name="newFileName">修复后保存的文件地址</param>[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions][System.Security.SecurityCritical]public static bool TextStyleRecovery(string fileName, ref string newFileName){try{using (var acDb = CreateNewDatabase(fileName)){acDb.TextStyleRecovery();acDb.SaveAs(newFileName, acDb.OriginalFileVersion);return true;}}catch (AccessViolationException){newFileName = Path.ChangeExtension(newFileName, "2.dwg");File.Copy(fileName, newFileName, true);return UsedRecoveryCommand(newFileName, 120000);}catch (System.Exception e){return false;}}/// <summary>/// 使用修复命令/// </summary>/// <param name="fileName">文件地址</param>/// <param name="milliseconds">等待命令退出的时间(以毫秒为单位)。</param>/// <returns>如果修复成功,则为true;否则为false;</returns>public static bool UsedRecoveryCommand(string fileName, int milliseconds){System.Diagnostics.Process accoreconsole = null;try{var scrComment = new StringBuilder();scrComment.AppendLine("secureload").AppendLine("0").AppendLine("netload").AppendLine(typeof(RealDwgHelper).Assembly.Location).AppendLine("CustomRecover");var scrPath = Path.ChangeExtension(fileName, "recover.scr");File.WriteAllText(scrPath, scrComment.ToString());var args = $"/i \"{fileName}\" /s \"{scrPath}\" /l zh-CN";var appPath = AutoCADHelper.FindConsoleApp(fileName);accoreconsole = new System.Diagnostics.Process();//accoreconsole.StartInfo.FileName = Common.GolbalSetter.AccoreConsoleAppPath;accoreconsole.StartInfo.FileName = appPath;accoreconsole.StartInfo.Arguments = args;accoreconsole.StartInfo.CreateNoWindow = true;accoreconsole.StartInfo.UseShellExecute = false;accoreconsole.Start();accoreconsole.WaitForExit(milliseconds);if (!accoreconsole.HasExited){accoreconsole.Kill();return false;}else{return accoreconsole.ExitCode == 0;}}catch (System.Exception e){accoreconsole?.Kill();Console.WriteLine("CADTool.RealDwg.RealDwgHelper.RecoveryCommand()发生异常!" + e.Message);return false;}}/// <summary>/// 创建新的Database/// </summary>/// <param name="dwgPath">文件路径</param>/// <param name="timeout">超时时间(单位毫秒)</param>/// <returns>返回一个Database实例对象</returns>public static Database CreateNewDatabase(string fileName, int timeout){if (timeout <= 0)throw new ArgumentOutOfRangeException(nameof(timeout), "值小于等于0");// 初始化依赖环境Initialize();// 创建database实例Database db = new Database(false, true);var cancellationTokenSource = new CancellationTokenSource(timeout);try{var dbCreationTask = Task.Factory.StartNew(() => LoadFile(db, fileName), cancellationTokenSource.Token);dbCreationTask.Wait();}catch (AggregateException e) when ((e.InnerException as TaskCanceledException) != null){Console.WriteLine("Database初始化超时。");}catch (AggregateException e) when (e.InnerException != null){throw e.InnerException;}catch{throw;}return db;}/// <summary>/// 载入文件/// </summary>/// <param name="db">数据库对象</param>/// <param name="dwgPath">文件地址</param>private static void LoadFile(Database db, string dwgPath){if (dwgPath.ToLower().EndsWith("dwg")){db.ReadDwgFile(dwgPath, FileShare.ReadWrite, true, "");}else if (dwgPath.ToLower().EndsWith("dxf")){db.DxfIn(dwgPath, dwgPath + ".log");}else{Console.WriteLine("不支持的格式");}db.CloseInput(true);}
}

2、开发过程中,经常会使用到注册表中的某些数据:

public static class RegistryHelper
{/// <summary>/// 打开AutoCAD注册表节点/// </summary>/// <returns>返回注册表节点</returns>public static RegistryKey OpenAutoCADKey(){var keyAutoCad = Registry.CurrentUser.OpenSubKey("Software\\Autodesk\\AutoCAD");return keyAutoCad;}/// <summary>/// 打开AutoCAD的指定版本号的注册表节点/// 默认打开CurVer/// </summary>/// <param name="version">版本代号</param>/// <returns>返回注册表节点</returns>public static RegistryKey OpenAutoCADVersionKey(string version = null){var acKey = OpenAutoCADKey();if (acKey == null)return null;string subKeyName = version;if (string.IsNullOrEmpty(version)){subKeyName = acKey.GetValue("CurVer").ToString();if (string.IsNullOrEmpty(subKeyName))return null;}return acKey.OpenSubKey(subKeyName);}/// <summary>/// 打开AutoCAD的默认版本下的指定语言的注册表节点/// 默认打开CurVer/// </summary>/// <param name="language">语言代号</param>/// <returns>返回注册表节点</returns>public static RegistryKey OpenAutoCADLanguageKey(string language = null){var acKey = OpenAutoCADVersionKey();if (acKey == null)return null;string subKeyName = language;if (string.IsNullOrEmpty(language)){subKeyName = acKey.GetValue("CurVer").ToString();if (string.IsNullOrEmpty(subKeyName))return null;}return acKey.OpenSubKey(subKeyName);}/// <summary>/// 打开AutoCAD的默认版本和语言下的Profiles注册表节点/// </summary>/// <returns>返回注册表节点</returns>public static RegistryKey OpenAutoCADProfilesKey(){var acKey = OpenAutoCADLanguageKey();if (acKey == null)return null;return acKey.OpenSubKey(@"Profiles\<<未命名配置>>");}/// <summary>/// 打开AutoCAD的默认Profiles下的General注册表节点/// </summary>/// <returns>返回注册表节点</returns>public static RegistryKey OpenAutoCADProfilesGeneralKey(){var acKey = OpenAutoCADProfilesKey();if (acKey == null)return null;return acKey.OpenSubKey("General");}
}

3、本地安装多个版本的CAD程序时,可以通过下面的一些方法,控制程序使用最符合需求的CAD版本:

public static class AutoCADHelper
{/// <summary>/// 获取AutoCAD支持文件搜索路径/// </summary>/// <returns>返回一个字符串</returns>public static string GetSupportedPath(){var acKey = RegistryHelper.OpenAutoCADProfilesGeneralKey();if (acKey == null)return string.Empty;return acKey.GetValue("ACAD", "").ToString();}/// <summary>/// 增加AutoCAD支持文件搜索路径/// </summary>/// <param name="path">需增加的路径</param>public static void AddAutoCADSupportedPath(string path){var acKey = RegistryHelper.OpenAutoCADProfilesGeneralKey();if (acKey == null)return;var acadValue = acKey.GetValue("ACAD", "").ToString();var paths = acadValue.Split(';');if (!paths.Contains(path)){acKey.SetValue("ACAD", acadValue + ";" + path);}}/// <summary>/// 获取完整的搜索路径/// </summary>/// <returns>返回一个字符串</returns>public static string GetSearchedFullName(){// 用户自定义环境变量Pathvar userPathVariable = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);// 用分号拼接return string.Format("{0};{1}", userPathVariable, GetSupportedPath());}/// <summary>/// 获取搜索路径地址数组/// </summary>/// <returns>返回一个字符串数组</returns>public static string[] GetSearchedPaths(){var path = GetSearchedFullName();if (string.IsNullOrEmpty(path))return new string[0];return path.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();}/// <summary>/// 获取所有AutoCAD程序的Roaming根目录/// </summary>/// <returns>返回所有AutoCAD程序的Roaming根目录</returns>public static string[] GetAllRoamableRootFolder(){//增加固定目录作为备选目录var spareFolders = new List<string>();spareFolders.Add("C:\\Program Files\\Autodesk\\AutoCAD 2014");spareFolders.Add("C:\\Program Files\\Autodesk\\AutoCAD 2019");var autocadKey = RegistryHelper.OpenAutoCADKey();if (autocadKey == null || autocadKey.SubKeyCount == 0)return spareFolders.ToArray();var subkeyNames = autocadKey.GetSubKeyNames();var folders = new List<string>();for (int i = 0; i < autocadKey.SubKeyCount; i++){var versionKey = autocadKey.OpenSubKey(subkeyNames[i]);var curver = versionKey.GetValue("CurVer")?.ToString();if (curver == null) continue;var curverKey = versionKey.OpenSubKey(curver);var folder = curverKey.GetValue("RoamableRootFolder")?.ToString();if (folder == null) continue;folders.Add(folder);}if (folders.Count <= 0){folders.AddRange(spareFolders);}return folders.ToArray();}/// <summary>/// 获取所有AutoCAD程序的安装目录/// </summary>/// <returns>返回所有AutoCAD程序的安装目录</returns>public static Dictionary<string, string> GetAllInstallationFolder(){var autocadKey = Registry.LocalMachine.OpenSubKey("Software\\Autodesk\\AutoCAD");if (autocadKey == null || autocadKey.SubKeyCount == 0)return null;var subkeyNames = autocadKey.GetSubKeyNames();var folders = new Dictionary<string, string>();for (int i = 0; i < autocadKey.SubKeyCount; i++){var versionKey = autocadKey.OpenSubKey(subkeyNames[i]);var folder = versionKey.OpenSubKey("InstalledProducts")?.GetValue("").ToString();if (folder == null) continue;folders.Add(subkeyNames[i], folder);}return folders;}/// <summary>/// 根据dwg版本号查找合适的accoreconsole.exe程序地址集合/// </summary>/// <param name="version">dwg格式文件版本号</param>/// <returns>返回accoreconsole.exe程序地址集合</returns>public static string[] FindConsoleAppCollection(DwgVersion version){var appPaths = GetAllInstallationFolder()?.ToDictionary(item => item.Key, item => Path.Combine(item.Value, "accoreconsole.exe"));if (appPaths != null){return appPaths.Where(item =>SupportLatestVersion.ContainsKey(item.Key) &&SupportLatestVersion[item.Key] >= version)?.OrderByDescending(item => SupportLatestVersion[item.Key]).Select(item => item.Value).ToArray();}return null;}/// <summary>/// 根据dwg版本号查找合适的accoreconsole.exe/// </summary>/// <param name="version">dwg格式文件版本号</param>/// <returns>返回accoreconsole.exe地址</returns>public static string FindConsoleApp(DwgVersion version){return FindConsoleAppCollection(version)?.First();}/// <summary>/// 查找最符合打开指定文件的accoreconsole.exe程序地址集合/// </summary>/// <param name="fileName">文件地址</param>/// <returns>返回accoreconsole.exe程序地址集合</returns>public static string[] FindConsoleAppCollection(string fileName){var acversion = GetACVersion(fileName);var dwgversion = ConvertDwgVersion(acversion);return FindConsoleAppCollection(dwgversion);}/// <summary>/// 查找最符合打开指定文件的accoreconsole.exe程序/// </summary>/// <param name="fileName">文件地址</param>/// <returns>返回accoreconsole.exe地址</returns>public static string FindConsoleApp(string fileName){return FindConsoleAppCollection(fileName)?.First();}/// <summary>/// AutoCAD各版本支持的最新dwg格式版本/// </summary>public static Dictionary<string, DwgVersion> SupportLatestVersion = new Dictionary<string, DwgVersion>{{"R19.1", DwgVersion.AC1027 },{"R23.0", DwgVersion.AC1032 }};/// <summary>/// 获取dwg文件版本号/// </summary>/// <param name="fileName">文件地址</param>/// <returns>返回版本号字符串</returns>public static string GetACVersion(string fileName){using (var reader = new StreamReader(fileName)){var chars = new char[6];reader.Read(chars, 0, chars.Length);return new string(chars);}}/// <summary>/// AC格式版本号转换为dwg格式版本号枚举值/// </summary>/// <param name="acversion">ac版本号</param>/// <returns>返回dwg格式版本号枚举值</returns>public static DwgVersion ConvertDwgVersion(string acversion){switch (acversion){case "MC0.0 ": return DwgVersion.MC0To0;case "AC1.2 ": return DwgVersion.AC1To2;case "AC1.50": return DwgVersion.AC1To50;case "AC2.10": return DwgVersion.AC2To10;case "AC1002": return DwgVersion.AC1002;case "AC1003": return DwgVersion.AC1003;case "AC1004": return DwgVersion.AC1004;case "AC1006": return DwgVersion.AC1006;case "AC1009": return DwgVersion.AC1009;case "AC1012": return DwgVersion.AC1012;case "AC1014": return DwgVersion.AC1014;case "AC1015": return DwgVersion.AC1015;case "AC1018": return DwgVersion.AC1800;case "AC1021": return DwgVersion.AC1021;case "AC1024": return DwgVersion.AC1024;case "AC1027": return DwgVersion.AC1027;case "AC1032": return DwgVersion.AC1032;default: return DwgVersion.Current;}}#region 【Purge】命令扩展/// <summary>/// 清理数据库/// </summary>/// <param name="db"></param>public static void DatabasePurge(this Database db){using (var trans = db.TransactionManager.StartTransaction()){TablePurge(db.BlockTableId);TablePurge(db.LayerTableId);TablePurge(db.LinetypeTableId);TablePurge(db.DimStyleTableId);TablePurge(db.RegAppTableId);TablePurge(db.TextStyleTableId);trans.Commit();}}/// <summary>/// 清理表数据/// </summary>/// <param name="tableId"></param>public static void TablePurge(ObjectId tableId){var acdb = tableId.Database;var acTrans = acdb.TransactionManager.TopTransaction;if (acTrans == null){throw new NullReferenceException("未开启事务, TransactionManager.TopTransaction is null");}var blockTable = (SymbolTable)acTrans.GetObject(tableId, OpenMode.ForRead);var ids = new ObjectIdCollection();foreach (ObjectId id in blockTable)ids.Add(id);acdb.Purge(ids);foreach (ObjectId id in ids){var obj = acTrans.GetObject(id, OpenMode.ForWrite);obj.Erase();}}/// <summary>/// 空间清理/// </summary>/// <param name="acDb"></param>/// <param name="layoutName"></param>public static void LayoutPurge(this Database acDb, string layoutName){HostApplicationServices.WorkingDatabase = acDb;var acLayoutMgr = LayoutManager.Current;if (acLayoutMgr.LayoutExists(layoutName)){var layoutId = acLayoutMgr.GetLayoutId(layoutName);using (var acTrans = acDb.TransactionManager.StartTransaction()){var acLayout = acTrans.GetObject(layoutId, OpenMode.ForRead) as Layout;// 清理图元if (acLayout.BlockTableRecordId.IsValid){var acBlkRec = (BlockTableRecord)acTrans.GetObject(acLayout.BlockTableRecordId, OpenMode.ForRead);foreach (var objId in acBlkRec){var obj = acTrans.GetObject(objId, OpenMode.ForWrite);obj.Erase();}}acTrans.Commit();}}else{acLayoutMgr.CreateLayout(layoutName);}}#endregion#region 【RECOVER】命令扩展/// <summary>/// 字体样式修复/// </summary>/// <param name="acDb">CAD数据库</param>/// <param name="newFileName">新的SHX字体文件</param>/// <param name="newBigFontFileName">新的大字体文件</param>public static void TextStyleRecovery(this Database acDb, string newFileName = "tssdeng.shx", string newBigFontFileName = "gbcbig.shx"){var names = new string[2];var actions = new Action<TextStyleTableRecord>[]{new Action<TextStyleTableRecord>(tsr => tsr.FileName = newFileName),new Action<TextStyleTableRecord>(tsr => tsr.BigFontFileName = newBigFontFileName)};// CAD支持的搜索路径var searchPaths = GetSearchedPaths();// 路径名称中的非法字符var invalidChars = new String(System.IO.Path.GetInvalidFileNameChars());var regFixFileName = new System.Text.RegularExpressions.Regex("[" + System.Text.RegularExpressions.Regex.Escape(invalidChars) + "]");using (var trans = acDb.TransactionManager.StartTransaction()){// 字体样式表using (var tst = (TextStyleTable)trans.GetObject(acDb.TextStyleTableId, OpenMode.ForRead)){foreach (var styleId in tst){using (var DbObj = trans.GetObject(styleId, OpenMode.ForWrite)){TextStyleTableRecord tsr = DbObj as TextStyleTableRecord;if (tsr is null){continue;}names[0] = tsr.FileName;names[1] = tsr.BigFontFileName;for (int i = 0; i < names.Length; i++){var name = names[i];if (!string.IsNullOrEmpty(name) && !regFixFileName.IsMatch(name) && !name.ToLower().EndsWith(".ttf")){if (!name.Contains('.')) name = name + ".shx";if (searchPaths.All(p => !System.IO.File.Exists(System.IO.Path.Combine(p, name)))){actions[i](tsr);}}}if (tsr.FileName.ToLower().EndsWith(".ttf")){string ttfFontPath = string.Format(@"{0}\fonts\{1}", System.Environment.GetEnvironmentVariable("WINDIR"), tsr.FileName);//系统FONT目录if (!File.Exists(ttfFontPath)){tsr.FileName = "simfang.ttf";}}else if (string.IsNullOrEmpty(tsr.FileName)){string fontName = tsr.Font.TypeFace;System.Drawing.Font font = new System.Drawing.Font(fontName, 10);if (font.Name != fontName){tsr.FileName = "simfang.ttf";}}}}}trans.Commit();}}#endregion
}

C#-CAD二开相关相关推荐

  1. cad二次开发——自动运行dll,加载菜单(收集)

    1.自动加载dll的方法(个人觉得下面第4个方法会更方便) cad加载dll_实现CAD插件启动自动加载的三种方法_weixin_39774556的博客-CSDN博客从网上或者别处淘来的CAD插件,效 ...

  2. cad二次开发——环境准备、命令行交互

    1.cad二开的准备工作 cad二次开发的sdk(官方的sdk下载地址,其中包含样例):AutoCAD ObjectARX SDK Platform Technologies | Autodesk D ...

  3. CAD二次开发之ArxDbg的安装

    一.背景 小伙伴门在做CAD二次开发时,是否需要对CAD的内部数据进行查看呢?通过ArxDbg插件,我们就能很方便的实现这一点. 二.如何加载和使用 2.1在命令栏输入 APPLOAD 2.2然后根据 ...

  4. 武汉BIM CAD 二次开发大会

    转载请复制以下信息: 原文链接: http://blog.csdn.net/joexiongjin/article/details/7472836 作者:  叶雄进 2012.4.18 这里向大家报告 ...

  5. lisp陡坎程序_(终稿)毕业论文设计_Autolisp在CAD二次开发中的应用.doc(最终版)最新版...

    <毕业论文:Autolisp在CAD二次开发中的应用.doc>由会员分享,可免费在线阅读全文,更多与<(终稿)毕业论文设计_Autolisp在CAD二次开发中的应用.doc(最终版) ...

  6. 新版二开cp盲盒小纸条月老小程序源码

    介绍: 新版二开cp盲盒小纸条月老小程序源码 最近抖音非常爆火的月老地摊项目,博主也是找了很多相关程序,并没有相关程序放出来,博主跟朋友动手写了这个小程序 网盘下载地址: http://kekewan ...

  7. revit二开之过滤族(Family)

    一.背景 小伙伴们在做revit二开时,可能会有过滤族(Family)的需求,如何实现呢? 二.方法 通过以下代码,就可以过滤出指定FamilyName的族了. var famType = new F ...

  8. CAD 二次开发 图层操作(3)取得指定图层下的所有对象id

    对于CAD二次开发的人来说,可能需要对某一图层下的实体(点,线,面域,块,三维实体)进行不同的操作.下面的方法,即可实现获取指定图层名称下的所有实体ID. 输入参数为图层名称: 返回值为:对象主键集合 ...

  9. 抖音seo源码.源代码开发可二开搭建/抖音seo优化系统代开发

    抖音seo源码源代码开发可二开搭建, 抖音seo源码,抖音seo矩阵系统源码技术搭建 抖音seo源码,抖音seo矩阵系统底层框架上支持了从ai视频混剪,视频批量原创产出,云端数字人视频制作,账号矩阵, ...

最新文章

  1. java获取注解的属性值_反射+自定义注解,实现获取注解标记的属性
  2. 渗透工具开发——XSS平台的命令行实现
  3. android scrollview 底部控件,Android ScrollView和屏幕底部的按钮
  4. 后端学习 - Java基础
  5. java 多线程和并行编程_Java 8中的并行和异步编程
  6. python表示当前目录_从Python脚本获取当前目录的父项
  7. 同一事务中未提交的写能读到吗_03、MySQL事务的隔离性分析
  8. 离上市又近一步!华为P40系列在工信部入网......
  9. 高性能反向代理软件HAProxy(一)之基本概念
  10. 手机网络游戏系统架构图
  11. ios charts显示固定个数_上次挂在了百度iOS二面不服气, 三月之期已到,这次终于拿下offer!...
  12. grep命令与正则表达式
  13. Atitit 图像处理 调用opencv 通过java  api   attilax总结
  14. 阿坝县人民医院管理系统软件硬件配置参数
  15. confluence 无法保存页面 排错记录
  16. java中laber字体颜色设置,QLabel:设置文本和背景的颜色
  17. sicily 1691 Abundance
  18. matlab迭代分水岭分割,matlab分水岭分割算法
  19. 用python画月亮和星空_用canvas画一轮明月,夜空与流星
  20. 华为研究院19级研究员几年心得终成趣谈网络协议文档,附讲解

热门文章

  1. 手机访问网站 点击手机号码直接拨打电话
  2. 查询所有分都大于80分的学生姓名
  3. 容积脉搏波的采集原理
  4. 成都c++语言青少年培训,成都小孩学信息学奥赛的好处-成都童程童美少儿编程培训金沙校区...
  5. mt4 谐波_【干货分享】比肩波浪理论,被誉为最难技术形态的谐波形态是什么?...
  6. 中国人工智能学会发布《2022年度中国人工智能学会-华为MindSpore学术奖励基金入选名单公示》...
  7. 利用外部程序对存储BIOS设置参数的CMOS RAM进行读取操作的可行性分析
  8. @craco/craco复写cra项目配置
  9. Linux/centOS安装lftp
  10. 局域网协议分类(计算机网络)