如何从 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,但没有成功
- 直接在autocad的命令行中手动
- 使用 c# 方法 SetSystemVariable()
- 与我们调用 InvokeMember("SendCommand") 的方式相同
- 在我们执行操作的同一个 Lisp 命令中
我查看了 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 和交易来处理潜在问题。
我正在尝试从 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,但没有成功
- 直接在autocad的命令行中手动
- 使用 c# 方法 SetSystemVariable()
- 与我们调用 InvokeMember("SendCommand") 的方式相同
- 在我们执行操作的同一个 Lisp 命令中
我查看了 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 和交易来处理潜在问题。