大部分编程语言都提供来了相关的api,用于获取当前运行的文件或者脚本的文件路径, 连windows批处理(bat)脚本都能获取当前脚本所在的路径,然而,autolisp就是做不到。

不仅autolisp做不到,visual lisp一样做不到,甚至连当前正在运行的脚本(cad插件)的文件名都获取不了。 visual lisp能获取到文件名的,只有部分类型的vlx文件,当vlx文件具有自己独立的命名空间(namespace)时, 才会出现在(vl-list-loaded-vlx)的返回值列表中,前提是这个vlx已经加载了。

因为语言本身、宿主环境都没有提供api,所以,通常情况下,autolisp是无法获取当前加载(运行)的lsp文件路径的。 本文的方法,获取当前加载(运行)的lsp文件路径仅限于特定情况下,也就是通过拖拽lsp文件到cad绘图区来加载, 并且仅限于获取当前加载的lsp文件的路径。

拖拽lsp文件到cad绘图区获取lsp文件路径的原理,就在于这个操作会触发1条autolisp语句,这条语句就是(load filename), 作用就是加载这个lsp文件。这条因拖拽lsp文件触发的load语句,和手动在命令行输入是一样的,也就是说, 拖拽操作使得cad自身向命令行发送了这条load语句。

我们知道,cad命令行的输入语句,都是有回显的,就是你输入什么,它会先在命令行显示出来,然后开始执行相关的操作。 上述load语句,它运行方式也是如此,先回显再执行其中的lisp语句。load语句的回显信息,恰恰就包含了这个lsp文件的路径, 因此,只要捕获这条回显信息,就能获取这个lsp文件的路径了。

如何捕获命令行的回显信息呢?

autocad有一个系统变量,名为lastprompt,保存的就是上一条回显信息。

至此,我们就解决了lsp文件所在路径的获取问题了。大致的流程如下:

flowchart

验证这个方法的方式很简单,新建一个空白lsp文件,写入如下2行lisp代码,

1
2
(print)
(alert (getvar "lastprompt"))

存盘,把这个lsp文件拖拽到cad绘图区,cad弹出一个显示有lsp文件路径的消息窗口,就算成功了。 消息窗应该就是与下图类似。

sample

重点来了,划重点了!

上述方法的成功应用,有一点需要特别地注意,在调用(getvar "lastprompt")前,必须要先(print)一下! (print)语句的作用,就是退出load语句的回显并将回显光标移动至下一行,这样,load语句回显信息才能成为上一条回显信息, 才能通过(getvar "lastprompt")捕获!那些试图通过lastprompt获取lsp文件路径却遭遇失败的,多半是败在了这里, 当然,这个load语句的回显不会自动退出,也许是个bug。

另外,本文方法并非仅仅适用于lsp文件,fas、vlx文件也是可以使用的。

最后,声明一下,本文的这个拖拽lsp文件到cad绘图区来获取lsp文件路径的方法,并非本人原创, 之所以在这里废话连篇地记录下来,是因为百度了几下都没有找到相关记录。有了好方法却不分享,很可恶,不是吗?