使用Python批处理运行autoLISP

使用Python批处理运行autoLISP,python,autocad,autolisp,Python,Autocad,Autolisp,我想在多个CAD文件(例如文件夹中的所有文件)上运行autoLISP。基本上,打开文件(DWG),运行LISP(包括,保存文件)并关闭。我不熟悉LISP,但不太熟悉Python 是否可以使用Python运行批处理?我知道如何用Python程序打开文件,但不知道如何运行LISP。或者,有人知道如何使用LISP运行批处理吗 到目前为止,我找到的解决方案涉及第三方软件和C。另外,我正在运行AutoCAD MEP 2018和Python 3.5。根据我的经验,批处理多个文件的最佳方法是使用AutoCAD

我想在多个CAD文件(例如文件夹中的所有文件)上运行autoLISP。基本上,打开文件(DWG),运行LISP(包括,保存文件)并关闭。我不熟悉LISP,但不太熟悉Python

是否可以使用Python运行批处理?我知道如何用Python程序打开文件,但不知道如何运行LISP。或者,有人知道如何使用LISP运行批处理吗


到目前为止,我找到的解决方案涉及第三方软件和C。另外,我正在运行AutoCAD MEP 2018和Python 3.5。

根据我的经验,批处理多个文件的最佳方法是使用AutoCAD脚本文件(
.scr

脚本仅用于打开每个图形,加载并运行适当的AutoLISP程序,然后保存并关闭图形,然后再移动到下一个图形文件

由于AutoLISP在文档名称空间中运行,因此当另一个图形处于活动状态时,评估将停止;但是,AutoCAD脚本文件将继续运行,直到脚本中的所有命令都已发出或脚本已中止


这种脚本的基本结构是:

_.open C:\Drawing1.dwg (load "MyProgram.lsp" nil) (c:MyCommand) _.qsave _.close
_.open C:\Drawing2.dwg (load "MyProgram.lsp" nil) (c:MyCommand) _.qsave _.close
_.open C:\Drawing3.dwg (load "MyProgram.lsp" nil) (c:MyCommand) _.qsave _.close
...
可以将上述内容另存为
MyScript.scr
,并使用AutoCAD
SCRIPT
命令从空白的新图形中运行

当然,还可以加入额外的错误检查,例如在评估之前检查AutoLISP程序是否已成功加载等

有关AutoCAD脚本文件的详细信息,我已将周围的AutoCAD脚本放在一起


考虑到以上内容,下一步是自动构建脚本文件本身(而不是手动编写几乎相同的行)

为此,有几个现有的应用程序:ScriptPro是众所周知的,不久前我也创建了自己的应用程序,它提供了一个基本界面,允许用户键入脚本文件的第一行,程序构造其余部分

为了提供一个现有的示例,我的应用程序还基于使用AutoLISP应用程序构造AutoCAD脚本文件的这一技术,该脚本文件随后用于在多个选定图形上评估AutoLISP函数



简而言之,尽管您明确说明了使用Python来执行此任务,但我认为在这种情况下没有必要这样做,因为一个非常简单的脚本文件(
.scr
)就足够了。

根据我的经验,批处理多个文件的最佳方法是使用AutoCAD脚本文件(
.scr

脚本仅用于打开每个图形,加载并运行适当的AutoLISP程序,然后保存并关闭图形,然后再移动到下一个图形文件

由于AutoLISP在文档名称空间中运行,因此当另一个图形处于活动状态时,评估将停止;但是,AutoCAD脚本文件将继续运行,直到脚本中的所有命令都已发出或脚本已中止


这种脚本的基本结构是:

_.open C:\Drawing1.dwg (load "MyProgram.lsp" nil) (c:MyCommand) _.qsave _.close
_.open C:\Drawing2.dwg (load "MyProgram.lsp" nil) (c:MyCommand) _.qsave _.close
_.open C:\Drawing3.dwg (load "MyProgram.lsp" nil) (c:MyCommand) _.qsave _.close
...
可以将上述内容另存为
MyScript.scr
,并使用AutoCAD
SCRIPT
命令从空白的新图形中运行

当然,还可以加入额外的错误检查,例如在评估之前检查AutoLISP程序是否已成功加载等

有关AutoCAD脚本文件的详细信息,我已将周围的AutoCAD脚本放在一起


考虑到以上内容,下一步是自动构建脚本文件本身(而不是手动编写几乎相同的行)

为此,有几个现有的应用程序:ScriptPro是众所周知的,不久前我也创建了自己的应用程序,它提供了一个基本界面,允许用户键入脚本文件的第一行,程序构造其余部分

为了提供一个现有的示例,我的应用程序还基于使用AutoLISP应用程序构造AutoCAD脚本文件的这一技术,该脚本文件随后用于在多个选定图形上评估AutoLISP函数



简而言之,尽管您明确说明了使用Python来执行此任务,但我认为在这种情况下没有必要这样做,因为一个非常简单的脚本文件(
.scr
)就足够了。

我实际上已经使用comtypes在Python2.7中实现了它

以下是测试用例的代码:

#Import needed modules
import os
import comtypes.client
from comtypes import COMError
from comtypes.client import CreateObject, GetModule, GetActiveObject

#Uncomment it if you need to load these type libraries.
'''
#Load all needed type libraries
GetModule("C:/Windows/System32/stdole2.tlb")
import comtypes.gen.stdole as ole
print "stdole2 successfully loaded"
GetModule("C:/Program Files/Common Files/Autodesk Shared/acax20enu.tlb")
import comtypes.gen._4E3F492A_FB57_4439_9BF0_1567ED84A3A9_0_1_0 as acax
print "acax20enu successfully loaded"
GetModule("C:/Program Files/Common Files/Autodesk Shared/AcSmComponents20.tlb")
import comtypes.gen._ED125AFF_6294_4BE4_81E2_B98DCBBA214E_0_1_0 as AcSm
print "AcSmComponents20 successfully loaded"
'''

def main():
    #1- Get the AutoCAD instance
    try:
        acad = GetActiveObject("AutoCAD.Application.20")
        print "AutoCAD is Active"
        print "########"
    except(OSError, COMError): #If AutoCAD isn't running, run it
        acad = CreateObject("AutoCAD.Application.20",dynamic=True)
        print "AutoCAD is successfuly Opened"
        print "########"

    #2- Get the paths to the lisp file and the dwg file
    directory_name = "E:\\Dir1\\Dir2" #replace it with a real path, use "\\" as directory delimiters.
    '''
    Note that "\\" is transformed automatically to "\", & in order to comply with
    the AutoLISP "load" function, every "\" must be transformed again to "/".
    '''

    temp=""
    for char in directory_name:
        if char == "\\":
            temp += "/"
        else:
            temp += char
    directory_name = temp
    filename = directory_name + "/TestDWG.dwg"
    lispfile = directory_name + "/linedraw.lsp"

    #3- Open the drawing file
    print "Opening Drawing File ..."
    doc = acad.Documents.Open(filename)
    print "Drawing is successsfuly Opened"
    print "########"

    #4- Construct the AutoLISP expression that loads AutoLISP files
    command_str = '(load ' + '"' + lispfile + '")' + " "

    #5-Execute the AutoLISP expression
    print "Sending AutoLISP Expression ..."
    print "Expression: " + command_str
    doc.SendCommand("(setq *LOAD_SECURITY_STATE* (getvar 'SECURELOAD)) ")
    doc.SendCommand("(setvar \"SECURELOAD\" 0) ")
    doc.SendCommand(command_str)
    doc.SendCommand("(setvar \"SECURELOAD\" *LOAD_SECURITY_STATE*) ")
    print "AutoLISP Expression is successfuly sent"
    print "########"

    #6- Save and Close the drawing file and AutoCAD application
    doc.Save()
    doc.Close()
    acad.Quit()

    print "Process Finished"
    print "__________"

if __name__ == '__main__':
    main()

实际上,我已经使用comtypes实现了Python2.7

以下是测试用例的代码:

#Import needed modules
import os
import comtypes.client
from comtypes import COMError
from comtypes.client import CreateObject, GetModule, GetActiveObject

#Uncomment it if you need to load these type libraries.
'''
#Load all needed type libraries
GetModule("C:/Windows/System32/stdole2.tlb")
import comtypes.gen.stdole as ole
print "stdole2 successfully loaded"
GetModule("C:/Program Files/Common Files/Autodesk Shared/acax20enu.tlb")
import comtypes.gen._4E3F492A_FB57_4439_9BF0_1567ED84A3A9_0_1_0 as acax
print "acax20enu successfully loaded"
GetModule("C:/Program Files/Common Files/Autodesk Shared/AcSmComponents20.tlb")
import comtypes.gen._ED125AFF_6294_4BE4_81E2_B98DCBBA214E_0_1_0 as AcSm
print "AcSmComponents20 successfully loaded"
'''

def main():
    #1- Get the AutoCAD instance
    try:
        acad = GetActiveObject("AutoCAD.Application.20")
        print "AutoCAD is Active"
        print "########"
    except(OSError, COMError): #If AutoCAD isn't running, run it
        acad = CreateObject("AutoCAD.Application.20",dynamic=True)
        print "AutoCAD is successfuly Opened"
        print "########"

    #2- Get the paths to the lisp file and the dwg file
    directory_name = "E:\\Dir1\\Dir2" #replace it with a real path, use "\\" as directory delimiters.
    '''
    Note that "\\" is transformed automatically to "\", & in order to comply with
    the AutoLISP "load" function, every "\" must be transformed again to "/".
    '''

    temp=""
    for char in directory_name:
        if char == "\\":
            temp += "/"
        else:
            temp += char
    directory_name = temp
    filename = directory_name + "/TestDWG.dwg"
    lispfile = directory_name + "/linedraw.lsp"

    #3- Open the drawing file
    print "Opening Drawing File ..."
    doc = acad.Documents.Open(filename)
    print "Drawing is successsfuly Opened"
    print "########"

    #4- Construct the AutoLISP expression that loads AutoLISP files
    command_str = '(load ' + '"' + lispfile + '")' + " "

    #5-Execute the AutoLISP expression
    print "Sending AutoLISP Expression ..."
    print "Expression: " + command_str
    doc.SendCommand("(setq *LOAD_SECURITY_STATE* (getvar 'SECURELOAD)) ")
    doc.SendCommand("(setvar \"SECURELOAD\" 0) ")
    doc.SendCommand(command_str)
    doc.SendCommand("(setvar \"SECURELOAD\" *LOAD_SECURITY_STATE*) ")
    print "AutoLISP Expression is successfuly sent"
    print "########"

    #6- Save and Close the drawing file and AutoCAD application
    doc.Save()
    doc.Close()
    acad.Quit()

    print "Process Finished"
    print "__________"

if __name__ == '__main__':
    main()

回答得好!谢谢,回答得很好!非常感谢。