如何从 C# 代码向 Autocad 静默发送同步 Lisp 命令?

How to silently send a synchronous Lisp command to Autocad from c# code?

我正在尝试从 C# 代码向 autocad 静默发送同步 Lisp 命令。

下面是我们如何向 autocad 发送同步命令。

string textToSend = $"(command-s \"_.-layout\" \"_t\" {filePath} {layoutName})";
object acadDoc = Application.DocumentManager.MdiActiveDocument.GetAcadDocument();
acadDoc.GetType().InvokeMember("SendCommand", BindingFlags.InvokeMethod, null, acadDoc, new[] { textToSend + "\n" });

该命令有效,但问题是该命令最终出现在 autocad 的命令行中并阻塞了使用我们的扩展的起草者的历史记录。

我们尝试修改系统变量 CMDECHO、CMDDIA 和 NOMUTT,但没有成功

我查看了 InvokeMember 参数,但没有看到任何可能影响命令显示的内容,例如 ActiveDocument.SendTextToExecute() 异步命令。

我们如何从 c# 代码静默地向 autocad 发送同步 Lisp 命令?

Ps:我不使用 WBlockCloneObjects() 的原因是因为它使我们的应用程序极不稳定。我真的不想在这个问题上打开整个蠕虫罐头,我只是说这个来解释为什么我最终得到了我的问题的解决方案。

我的问题标题具有误导性。我不需要需要 到 运行 lisp 代码,我需要 运行 acad 命令行中的命令。恰好 acad 的命令行接受 lisp 代码,所以这就是我正在使用的。

我没有使用 运行ning lisp 代码,而是使用方法 ActiveDocument.Editor.Command() 将我的命令发送到 autocad。该方法是同步的,受系统变量影响cmdecho.

我遇到了后续问题;因为我是从带有 RelayCommand 的横幅中的按钮调用此方法,Editor.Command 抛出异常 eInvalidInput 因为我在应用程序上下文而不是文档上下文中。

处理此问题的最佳方法是将我的第一个方法一分为二,并使用 ActiveDocument.SendStringToExecute() 调用第二个方法,后者使用命令行,因此我最终进入文档上下文。但是因为 SendstringToExecute() 是异步的,所以我不得不稍微修改一下我的方法的逻辑。

这是最终结果(简化)

private Layout Layout;

private RelayCommand _Command_Test;
public RelayCommand Command_Test
{
    get
    {
        if (_Command_Test == null)
        {
            _Command_Test = new RelayCommand(
                (param) =>
                {
                    FirstMethod();
                },
                (param) =>
                {
                    return true;
                }
            );
        }
        return _Command_Test;
    }
}

[CommandMethod("FirstMethod")]
public void FirstMethod()
{
    // Many actions and processing
    Layout = new Layout(/*With stuff*/);
    Application.DocumentManager.MdiActiveDocument.SendStringToExecute("SecondMethod ", true, false, false);
}

[CommandMethod("SecondMethod")]
public void SecondMethod()
{
    short cmdecho = (short)Application.GetSystemVariable("cmdecho");
    Application.SetSystemVariable("cmdecho", 0);
    
    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
    ed.Command("_.-layout", "_t", Layout.FilePath, Layout.Name);
    
    Application.SetSystemVariable("cmdecho", cmdecho);
    
    // Actions that need to be ran after the command
}
  • 我不得不以不同的方式拆分我的第一个方法以获得两组同步操作。
  • 因为CommandMethod不能接收参数,只好在class.
  • 的字段中存储信息
  • 我在此处显示的代码中跳过了它,但我当然使用了 try-catches 和交易来处理潜在问题。