明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3102|回复: 16

C#怎样获取当前CAD已加载ARX程序列表(已解决获取天正多行文字的难题)

[复制链接]
发表于 2025-6-7 23:03:15 | 显示全部楼层 |阅读模式
本帖最后由 smartplot 于 2025-6-9 09:47 编辑

如题,请问各位老师,怎样使用C#获取当前cad已加载了哪些arx程序的路径,我主要是想用来获取当前cad所加载  tch_kernal.arx  文件的路径,用于读取天正多行文字的内容。
回复

使用道具 举报

 楼主| 发表于 2025-6-8 22:35:42 | 显示全部楼层
本帖最后由 smartplot 于 2025-6-8 22:38 编辑

Bao_lai 发表于 2025-6-8 21:09
PS:我这边用这个入口点,发现这个入口点对天正的单行和多行文字可以通用,不过有一个小问题,每个图元仅 ...


        public static void ReadTarchText()
        {
        
            try
            {
                // 创建数据库事务
                using var tr = new DBTrans();
                // 提示用户选择天正文字实体
                var entRes = Env.Editor.GetEntity("选择天正文字: \n");

                // 如果用户未正确选择实体,则退出方法
                if (entRes.Status != PromptStatus.OK)
                    return;

                // 获取选中的实体对象
                var tarchText = tr.GetObject<Entity>(entRes.ObjectId);
                // 如果实体对象为空,则退出方法
                if (tarchText is null)
                    return;

                // 获取非托管对象的指针
                IntPtr unmanagedPtr = tarchText.UnmanagedObject;
                // 如果非托管对象指针为空,则输出错误信息并退出方法
                if (unmanagedPtr == IntPtr.Zero)
                {
                    Env.Print("无法获取非托管对象指针");
                    return;
                }

                // 调用非托管方法获取文本内容的指针
                IntPtr nativeText = GetText_Native(unmanagedPtr);
                // 如果文本内容的指针不为空,则将其转换为字符串并输出
                if (nativeText != IntPtr.Zero)
                {
                    string text = Marshal.PtrToStringUni(nativeText);
                    if (text is not null)
                        Env.Print(text);
                }
            }
            // 捕获并输出异常信息
            catch (Exception ex)
            {
                Env.Print($"发生异常: {ex.Message}");
            }
        }


评分

参与人数 1明经币 +1 收起 理由
Bao_lai + 1 赞一个!

查看全部评分

回复 支持 1 反对 0

使用道具 举报

发表于 2025-6-8 21:09:52 | 显示全部楼层
本帖最后由 Bao_lai 于 2025-6-8 21:21 编辑
smartplot 发表于 2025-6-8 05:54
[DllImport("tch_kernal.arx", CharSet = CharSet.Unicode, CallingConvention = CallingConvent ...

PS:我这边用这个入口点,发现这个入口点对天正的单行和多行文字可以通用,不过有一个小问题,每个图元仅能操作一次,如果对已经操作过的图元第二次操作时,就会崩溃掉。不知道你那边测试有没有这样的情况。

  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System.Runtime.InteropServices;


  6. namespace CAD_天正文字
  7. {
  8.     public static class Class1
  9.     {

  10.         //天正多行文字
  11.         [DllImport("tch_kernal.arx", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?GetText@TDbText@@QEBAPEB_WXZ")]
  12.         private static extern string GetText_Native(IntPtr tchMText);


  13.         [CommandMethod("TT")]
  14.         public static void TT()
  15.         {
  16.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  17.             Database db = doc.Database;
  18.             Editor ed = doc.Editor;

  19.             TypedValue[] values = new TypedValue[1];
  20.             values.SetValue(new TypedValue((int)DxfCode.Start, "TCH_TEXT,TCH_MTEXT"), 0);
  21.             SelectionFilter filter = new SelectionFilter(values);

  22.             PromptSelectionOptions pso = new PromptSelectionOptions();
  23.             pso.MessageForAdding = "\n请选择天正文字对象";
  24.             pso.RejectObjectsOnLockedLayers = true;

  25.             PromptSelectionResult psr = ed.GetSelection(pso, filter);
  26.             if (psr.Status != PromptStatus.OK) { return; }
  27.             SelectionSet sSt = psr.Value;

  28.             using (Transaction trans = doc.TransactionManager.StartTransaction())
  29.             {
  30.                 BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
  31.                 BlockTableRecord btrMs = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

  32.                 foreach (ObjectId id in sSt.GetObjectIds())
  33.                 {
  34.                     Entity ent = (Entity)trans.GetObject(id, OpenMode.ForRead);

  35.                     string tchText = GetText_Native(ent.UnmanagedObject);

  36.                     ed.WriteMessage("\n" + tchText);
  37.                 }

  38.                 trans.Commit();
  39.             }
  40.         }
  41.     }
  42. }

回复 支持 反对

使用道具 举报

发表于 2025-6-7 23:37:00 | 显示全部楼层
方法特点
Process.Modules最简单,但包含托管DLL
EnumProcessModules类似C++版本,可以获取所有模块
ToolHelp32更底层,适合需要精确控制的情况过滤托管DLL适用于只想查看非托管DLL的情况
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-8 05:54:49 | 显示全部楼层
Bao_lai 发表于 2025-6-7 23:16
PS:顺带问一下,天正的多行文字,用C#获得,你怎么实现的?

        [DllImport("tch_kernal.arx", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
            EntryPoint = "?GetText@TDbText@@QEBAPEB_WXZ")]
        private static extern IntPtr GetText_Native(IntPtr tchElev);

        // 天正文字读取
        [CommandMethod(nameof(Tztext))]

        /// <summary>
        /// 提取天正文字实体的文本内容并输出
        /// </summary>
        public static void Tztext()
        {
            try
            {
                // 创建数据库事务
                using var tr = new DBTrans();
                // 提示用户选择天正文字实体
                var entRes = Env.Editor.GetEntity("选择天正文字: \n");

                // 如果用户未正确选择实体,则退出方法
                if (entRes.Status != PromptStatus.OK)
                    return;

                // 获取选中的实体对象
                var tarchText = tr.GetObject<Entity>(entRes.ObjectId);
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-8 09:15:46 | 显示全部楼层
你有种再说一遍 发表于 2025-6-7 23:37
方法特点
Process.Modules最简单,但包含托管DLL
EnumProcessModules类似C++版本,可以获取所有模块

请问VS2022+CAD2020 调试时,只要含有天正对象,或打开的是天正,就会卡死在天正启动界面,但是用Rider就能正常调试,这是什么原因导致的
回复 支持 反对

使用道具 举报

发表于 2025-6-8 12:01:09 来自手机 | 显示全部楼层
GetText@TDbText@@QEBAPEB_WXZ 原来是这个入口点呀,我一直去尝试的是TMEXT,误区了么,晚点试试。感谢~
回复 支持 反对

使用道具 举报

发表于 2025-6-8 20:44:09 | 显示全部楼层
smartplot 发表于 2025-6-8 09:15
请问VS2022+CAD2020 调试时,只要含有天正对象,或打开的是天正,就会卡死在天正启动界面,但是用Rider就 ...

http://bbs.mjtd.com/forum.php?mod=attachment&aid=MTQzMTAyfDA3MDU3OWRmMmJiMTM0YzZiNzQzM2JmYzYxOTZlNzQyfDE3NTk2ODYxODU%3D&request=yes&_f=.png

q其实并没有卡死在启动截面,当调试的环境有天正时,加载时会触发中断模式,你手动点一下继续执行,加载天正环境就可以了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-8 22:44:15 | 显示全部楼层
Bao_lai 发表于 2025-6-8 21:09
PS:我这边用这个入口点,发现这个入口点对天正的单行和多行文字可以通用,不过有一个小问题,每个图元仅 ...

这样改写后可以实现单行文字和多行文字的读写工作
回复 支持 反对

使用道具 举报

发表于 2025-6-9 09:05:05 | 显示全部楼层
smartplot 发表于 2025-6-8 22:35
Bao_lai 发表于 2025-6-8 21:09
PS:我这边用这个入口点,发现这个入口点对天正的单行和多行文字可以通用 ...

按你这个写法可以,没问题,非常感谢。
我那种调用方法,不知道为啥会有问题。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-10-6 01:43 , Processed in 0.201796 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表