CAD Revit 二次开发开启控制台打印调试信息

发布时间 2023-10-27 12:47:58作者: 百年一梦

第一步:编写控制台帮助类,调用kernel32.dll中控制台API

控制台帮助类
public class ConsoleHelper
    {

        private const uint STD_INPUT_HANDLE = 0xfffffff6;
        private const uint STD_OUTPUT_HANDLE = 0xfffffff5;
        private const uint STD_ERROR_HANDLE = 0xfffffff4;
        private const uint ATTACH_PARENT_PROCESS = 0xffffffff;
        private const int HWND_TOPMOST = -1;
        private const int SWP_NOMOVE = 0x0002;
        private const int SWP_NOSIZE = 0x0001;
        private static int stdin;
        private static int stdout;

        [DllImport("kernel32.dll")]
        private static extern bool AttachConsole(uint dwProcessId);
        [DllImport("kernel32.dll")]
        private static extern bool AllocConsole();
        [DllImport("kernel32.dll")]
        private static extern bool FreeConsole();
        [DllImport("kernel32.dll")]
        private static extern int GetStdHandle(uint nStdHandle);
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetConsoleWindow();
        [DllImport("kernel32.dll")]
        private static extern bool WriteConsole(int hConsoleOutput,
        string lpBuffer,
        int nNumberOfCharsToWrite,
        ref int
        lpNumberOfCharsWritten,
        int lpReserved);
        [DllImport("kernel32.dll")]
        public static extern bool ReadConsole(int hConsoleInput,
        StringBuilder lpBuffer,
        int nNumberOfCharsToRead,
        ref int lpNumberOfCharsRead,
        int lpReserved);
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetWindowPos(
          IntPtr hWnd,
          IntPtr hWndInsertAfter,
          int x,
          int y,
          int cx,
          int cy,
          int uFlags);

        /// <summary>
        /// 打开控制台,程序初始化时调用一次
        /// </summary>
        public static void OpenConsole() {
            //创建控制台
            AllocConsole();
            //将控制台浮于窗体最上层
            IntPtr hWnd = GetConsoleWindow();
            if (hWnd != null) {
                SetWindowPos(hWnd, new IntPtr(HWND_TOPMOST), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
            }
            //获取控制台输入输出流句柄
            stdin = GetStdHandle(STD_INPUT_HANDLE);
            stdout = GetStdHandle(STD_OUTPUT_HANDLE);
        }
        /// <summary>
        /// 关闭控制台
        /// </summary>
        public static void CloseConsole() {
            FreeConsole();
        }
        /// <summary>
        /// 控制台打印
        /// </summary>
        /// <param name="s"></param>
        public static void WriteLine(string s)
        {
            int len = 0;
            WriteConsole(stdout, s + "\r\n", s.Length + 2, ref len, 0);
        }
        /// <summary>
        /// 读取控制台数据
        /// </summary>
        /// <returns></returns>
        public static string ReadLine()
        {
            int len = 0;
            StringBuilder sb = new StringBuilder();
            ReadConsole(stdin, sb, 256, ref len, 0);
            return sb.ToString(0, sb.Length - 2);
        }
    }

第二步:初始化控制台帮助类,构建控制台并将其浮于所有窗体之上

(注意:一个进程只需要初始化一次即可)

控制台初始化
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    class RegistryCmd : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                //ApplicationRegistry.Register(commandData.Application);
#if DEBUG
                //控制台初始化
                ConsoleHelper.OpenConsole();
                //控制台打印
                ConsoleHelper.WriteLine("测试");
#endif
                return Result.Succeeded;
            }
            catch (Exception ex) {
                message = ex.Message;
                return Result.Failed;
            }
        }
    }

第三步:控制台打印,在需要打印位置调用静态打印函数即可

ConsoleHelper.WriteLine("测试");

效果演示

image