本帖最后由 smartplot 于 2025-6-9 09:47 编辑

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


网友答: 本帖最后由 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}");
            }
        }




网友答: 本帖最后由 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. }



网友答: 方法特点
Process.Modules最简单,但包含托管DLL
EnumProcessModules类似C++版本,可以获取所有模块
ToolHelp32更底层,适合需要精确控制的情况过滤托管DLL适用于只想查看非托管DLL的情况


网友答:
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-7 23:37
方法特点
Process.Modules最简单,但包含托管DLL
EnumProcessModules类似C++版本,可以获取所有模块

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

网友答: GetText@TDbText@@QEBAPEB_WXZ 原来是这个入口点呀,我一直去尝试的是TMEXT,误区了么,晚点试试。感谢~

网友答:
smartplot 发表于 2025-6-8 09:15
请问VS2022+CAD2020 调试时,只要含有天正对象,或打开的是天正,就会卡死在天正启动界面,但是用Rider就 ...

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

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


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

这样改写后可以实现单行文字和多行文字的读写工作

网友答:
smartplot 发表于 2025-6-8 22:35
Bao_lai 发表于 2025-6-8 21:09
PS:我这边用这个入口点,发现这个入口点对天正的单行和多行文字可以通用 ...

按你这个写法可以,没问题,非常感谢。
我那种调用方法,不知道为啥会有问题。
  • 上一篇:尝试上车net
  • 下一篇:没有了