關於自動載入和執行 AutoLISP 常式概述

在圖面階段作業期間的特定時間內啟動並執行指令或函數時,載入 AutoLISP 常式。

AutoCAD 系列產品可自動載入三個使用者可定義的檔案內容:acad.lspacaddoc.lsp 以及目前自訂檔隨附的 MNL 檔。

依預設,acad.lsp 檔只會載入一次 (當程式啟動時),而 acaddoc.lsp 則可透過每個個別文件 (或圖面) 載入。基於此,您可以將 acad.lsp 檔的載入與應用程式的啟動關聯,而將 acaddoc.lsp 檔的載入與文件 (或圖面) 的開啟關聯。透過變更系統變數 ACADLSPASDOC 的設定,您可以修改載入這些啟動檔的預設方式。

如果這些檔案中的其中一個定義特殊類型的函數 S::STARTUP,則此常式將在完全初始化圖面後立即執行。做為替代方案,APPLOAD 指令提供有「啟動套件」選項,可以載入指定的應用程式而無需編輯任何檔案。

AutoCAD 系列產品並未提供 acad.lspacaddoc.lsp 啟動檔。這些檔案需由使用者建立並維護。

註: 從 AutoCAD 2014 系列產品開始,自訂應用程式必須使用「安全模式」;當 SECURELOAD 系統變數設定為 1 或 2。當在安全模式作業下,程式僅限於載入並執行包含來自可信任的位置之程式碼的檔案;可信任的位置由 TRUSTEDPATHS 系統變數指定。

指令自動載入器

當您載入 AutoLISP 檔案時,無論您實際上是否使用指令,檔案中的指令定義都會佔用記憶體。而使用 AutoLISP 的 autoload 函數,您同樣可以使用指令,但卻不必將整個常式載入記憶體。將以下程式碼加入至 acaddoc.lsp 檔中,以自動從 cmds.lsp 檔載入指令 CMD1、CMD2 和 CMD3,以及從 newcmd.lsp 檔載入 NEWCMD 指令。

(autoload "CMDS" '("CMD1" "CMD2" "CMD3")) 
(autoload "NEWCMD" '("NEWCMD"))

當您第一次於指令提示下輸入自動載入的指令時,AutoLISP 會從關聯的檔案中載入整個指令定義。AutoLISP 針對 ObjectARX 應用程式還提供有 autoarxload 函數。

註: 名稱相似的 AutoLISP 啟動檔依據它們的修改時間戳記載入;具有最近時間戳記的 LSP 檔會被載入,除非您指定完整的檔名 (包括副檔名)。

ACAD.LSP 檔

如果您需要經常使用特定的 AutoLISP 常式,則可以建立一個 acad.lsp 檔。啟動 AutoCAD 時,它將在支援檔搜尋路徑中搜尋 acad.lsp 檔。如果找到 acad.lsp 檔,則將其載入記憶體。

因為 acad.lsp 用於應用程式特定的啟動常式,所以所有在 acad.lsp 檔中定義的函數與變數僅在第一個圖面中可用。您可能要將在所有文件中均可用的常式從 acad.lsp 檔移至 acaddoc.lsp 檔。

建議使用的 acad.lspacaddoc.lsp 功能可以由系統變數 ACADLSPASDOC 取代。如果將系統變數 ACADLSPASDOC 設為 0 (預設設定),則 acad.lsp 檔僅會載入一次,即在應用程式啟動時載入。如果設定為 1,則當建立新圖面或開啟既有圖檔時會重新載入 acad.lsp 檔。

acad.lsp 檔可以包含一個或多個常式的 AutoLISP 程式碼,也可以僅包含一系列 load 函數呼叫。後者是比較理想的方式,因為修改較為容易。如果將以下的程式碼另存為 acad.lsp 檔,則會在每次啟動程式時載入檔案 mysessionapp1.lspdatabasesynch.lspdrawingmanager.lsp

(load "mysessionapp1")
(load "databasesynch")
(load "drawingmanager")
註: 請勿修改保留的 acad<版本>.lsp 檔。Autodesk 可提供 acad<版本>.lsp 檔,其中包含必要的版本特定 AutoLISP 定義函數。將此檔案載入記憶體之後,會立即載入 acad.lsp 檔。<版本> 表示 AutoCAD 系列產品的版本,例如 acad2023.lsp 表示 AutoCAD 2023 系列產品所載入的檔案。

ACADDOC.LSP 檔

acaddoc.lsp 檔與每個文件 (或圖面) 的初始化作業相關聯。如果您想要在每次啟動新圖檔 (或開啟既有的圖面) 時都將 AutoLISP 的常式資源庫載入,此檔案就非常有用。

每次開啟圖面時,AutoCAD 都會在資源庫路徑中搜尋 acaddoc.lsp 檔。如果找到了,AutoCAD 就會將它載入記憶體。無論如何設定 ACADLSPASDOC,acaddoc.lsp 檔始終會與圖面一起載入。

大多數使用者會針對所有基於文件的 AutoLISP 常式使用單一 acaddoc.lsp 檔。程式會按照資源庫路徑定義的順序搜尋 acaddoc.lsp 檔,因此,使用此功能,每個圖面目錄中都可以有一個不同的 acaddoc.lsp 檔,它可為特定類型的圖面或工作載入特定的 AutoLISP 常式。

acad.lsp 檔可以包含一個或多個常式的 AutoLISP 程式碼,也可以僅包含於一系列 load 函數呼叫。後者是比較理想的方式,因為修改較為容易。如果將以下程式碼另存成 acaddoc.lsp 檔,則檔案 mydocumentapp1.lspbuild.lspcounter.lsp 會在每次開啟新文件時載入。

(load "mydocumentapp1")
(load "build")
(load "counter")
註: 請勿修改保留的 acad<版本>doc.lsp 檔。Autodesk 可提供 acad<版本>doc.lsp 檔,其中包含必要的版本特定 AutoLISP 定義函數。將此檔案載入記憶體之後,會立即載入 acaddoc.lsp 檔。<版本> 表示 AutoCAD 系列產品的版本,例如 acaddoc2023.lsp 表示 AutoCAD 2023 系列產品所載入的檔案。

MNL 檔和 AutoLISP 功能表自訂

程式在載入自訂 (CUI/CUIx) 檔時會搜尋檔名相符的 MNL 檔。如果找到了,AutoCAD 就會將該檔案載入記憶體。此功能可確保已載入進行使用者介面元素適當作業所需的 AutoLISP 函數。

例如,自訂檔 acad.cuix 會尋找 acad.mnl,該檔案可在自訂檔中定義使用者介面元素使用的許多 AutoLISP 功能。載入 acaddoc.lsp 檔之後,才載入 MNL 檔。

註: 如果自訂檔是使用語法類似於 (command "menu" "newmenu") 的 AutoLISP command 函數載入的,則直到整個 AutoLISP 常式執行後,才會載入關聯的 MNL 檔。
(command "menu" "newmenu")

(princ "Newmenu utilities… Loaded.")
(Princ)

在此範例中,princ 函數的呼叫可用於顯示狀態訊息。第一次使用 princ 會於指令提示下顯示以下內容:

Newmenu utilities… Loaded。

第二個 princ 呼叫用來結束 AutoLISP 函數。如果沒有第二個 princ 呼叫,則以上訊息將顯示兩次。如前所述,您可以在 load 函數的呼叫中包括 onfailure 引數來做為額外的預防措施。

S::STARTUP 函數:後初始化執行

您可以定義 S::STARTUP 函數,以在初始化圖面後執行任何需要的設置作業。

啟動 LISP 檔 (acad.lspacaddoc.lsp 和 MNL) 在完全初始化圖面前即會全部載入記憶體。一般來講,這並不會造成問題,除非您想使用 command 函數,該函數在完成初始化圖面之前不能保證可以使用。

如果使用者定義的函數 S::STARTUP 包含在 acad.lspacaddoc.lsp 或 MNL 檔中,則在進入新圖面或開啟既有圖面時會呼叫它。因此,您可以將 S::STARTUP 的定義併入 AutoLISP 啟動檔中,以執行所有設置作業。

例如,如果您想要加入一則訊息,然後切換至 BHATCH 指令,以取代標準 HATCH 指令,則可使用包含以下內容的 acaddoc.lsp 檔:

(defun C:HATCH ( ) 
  (alert "Using the BHATCH command!")
  (princ "\nEnter OLDHATCH to get to real HATCH command.\n")
  (command "BHATCH")
  (princ)
) 
(defun C:OLDHATCH ( ) 
  (command ".HATCH")
  (princ)
) 
(defun-q S::STARTUP ( ) 
  (command "undefine" "hatch") 
  (princ "\nRedefined HATCH to BHATCH!\n")
)

在初始化圖面之前,可使用 defun 函數重新定義 HATCH 和 OLDHATCH。在初始化圖面之後,會呼叫 S::STARTUP 函數,而 HATCH 的標準定義則會被取消。

註: 若要附加 S::STARTUP 函數,則必須使用 defun-q 函數而不是 defun 函數來定義該函數。

因為 S::STARTUP 函數可在多個位置 (acad.lspacaddoc.lsp、MNL 檔或從上述任何檔案中載入的任何其他 AutoLISP 檔) 定義,所以有可能會覆蓋先前定義的 S::STARTUP 函數。

下列範例展示一種能確保您的啟動函數可以和其他函數一起使用的方法。

(defun-q MYSTARTUP ( )

... 您的啟動函數 …

)
(setq S::STARTUP (append S::STARTUP MYSTARTUP))

以上程式碼將您的啟動函數附加至既有 S::STARTUP 函數的程式碼中,然後重新定義 S::STARTUP 函數以包括您的啟動程式碼。此新定義的函數可以正常作業,並不會受到之前 S::STARTUP 函數的影響。