KEMBAR78
Deploy and Support Autolisp | PDF | Computing | Software Engineering
0% found this document useful (0 votes)
41 views55 pages

Deploy and Support Autolisp

This document outlines best practices for deploying and supporting AutoLISP programs, including creating custom help topics, supporting multiple languages, and defining plug-in bundles. It emphasizes the importance of documentation and user support in enhancing the user experience and provides practical examples of how to implement help functions within AutoCAD. The author, Lee Ambrosius, shares insights from his extensive experience with AutoCAD programming and customization.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views55 pages

Deploy and Support Autolisp

This document outlines best practices for deploying and supporting AutoLISP programs, including creating custom help topics, supporting multiple languages, and defining plug-in bundles. It emphasizes the importance of documentation and user support in enhancing the user experience and provides practical examples of how to implement help functions within AutoCAD. The author, Lee Ambrosius, shares insights from his extensive experience with AutoCAD programming and customization.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

SD20507

Deploy and Support AutoLISP Programs Like a Pro


Lee Ambrosius
Autodesk, Inc.

Learning Objectives
 Learn how to create and implement custom help topics
 Learn how to support multiple languages
 Learn how to deploy programs and define plug-in bundles
 Learn how to trust and digitally sign AutoLISP program files

Description
Do you write AutoLISP programs and need to share them with users inside or outside your
company? Do you have users who use different languages or releases of AutoCAD
software? Sharing—more commonly referred to as “deploying” in the programming
community—program files can get complicated and cause those new to programming to
feel overwhelmed. This session will provide an overview of the best practices that you can
use to simplify the deployment and support of your custom AutoLISP programs. This
session features AutoCAD.

Your AU Expert
Lee Ambrosius is a Principal Learning Experience Designer at Autodesk, Inc., for the AutoCAD
software and AutoCAD LT software products. He works primarily on the CAD administration,
customization, and developer documentation. Lee has also worked on the user documentation
for AutoCAD on Windows and Mac. He has presented on a wide range of topics at Autodesk
University over the past decade plus, from general AutoCAD customization to Autodesk
ObjectARX technology. Lee has authored a number of AutoCAD-related books, with his most
recent project being AutoCAD Platform Customization: User Interface, AutoLISP, VBA, and
Beyond published by Wiley & Son’s. When he’s not writing, you can find him roaming various
community forums, posting articles on his blog, or tweeting AutoCAD-related information.

Twitter: @leeambrosius
Email: lee.ambrosius@autodesk.com
Blog: http://hyperpics.blogs.com

Page 1
1 Introduction
Learning something new can be exhilarating and scary all at the same time, with time things that
were once new become part of the everyday norm. For me, the adventure into AutoLISP
programming started about 20 years ago, while for you it might have been hours, days, or years
ago. When you first started programming doesn’t matter, but you most likely had some doubt
and excitement in the beginning. While I had some doubt about whether the concept of
programming was appealing to me, it was the “siren call” of the benefits that pulled me in;
getting stuff done faster, reducing repetitive tasks, and enforcing consistencies across all
drawings. I am sure you might be able to tell a similar story as to why you initially got started
developing with the AutoLISP programming language.
As time went along and I became more secure in my programming skills and the programs I
wrote, I wanted to share those programs with others so they could benefit from them too. While
I was excited to share my programs with others and show off how cool I thought they were, I
learned quickly that sharing a custom program wasn’t just giving out an AutoLISP (LSP) file. All
the information about how to run and use the custom programs defined in the LSP files I wanted
to share was stuck in my head; good for me, but less than ideal for the users that didn’t know
how to program with AutoLISP.
Along with learning that everything can’t be stuck in my head when it came to sharing my
custom programs, I learned rather quickly that users seem to think programmers are interested
in providing support and without support they are less likely to actually use your custom
programs. Then once you do get them to use your custom programs, they tend to have
opinions about them, making you wonder why you even shared them to begin with. Supporting
custom programs can often be more time consuming than writing the actual programs
themselves, but it doesn’t have to be that way with a bit of planning. The type and level of
support you might need to provide is typically determined by:
 Company size; individual (one man shop), small, medium, or large
 Location of the users; local (on-site/nearby) or remote
 Make-up of the user base; those that might know how to program versus those that
don’t
As the programmer of custom programs, some of the support tasks that you might need to get
involved with are:
 Troubleshooting
 Training and knowledge transfer
 Deployment/installing
While this might sound a bit overwhelming or complicated, the sections in this handout will help
you understand and plan for these support tasks.

Page 2
2 Implement Custom Help
Documenting source code is one of the least favorite activities of a developer, but whether
comments are added to the source code isn’t very helpful to the end users. Documentation isn’t
something that many developers think about, but it is an essential part of the overall user
experience. Documentation is can be a broad subject that includes:
 Prompt and error messages in a custom program
 Listing of commands or functions exposed by custom programs in which the user
can utilize
 Information about the options or expected values for exposed commands and
functions
 Concepts required to understand the custom programs
 Tutorials that explain how to use the custom programs
Documentation should be considered the first line of support and an integral part of any custom
program. Unless you want to give out your email address and phone number, and dedicate
time 24/7 to your deployed custom programs you will want to provide some level of basic
documentation. Start small, you don’t need to write a manual the first day you release your
custom programs.
When you write prompt messages, make sure they are clearly worded and short; long and
wordy prompt messages should be avoided to reduce confusion by the end user or even the
possibility of the message being missed entirely. If the user Command prompt is not docked
and is small, longer prompt messages might be pushed up and out of the history very quickly.
You might consider breaking a wordy prompt message, if related to request input, into multiple
requests for input or move some of the heavier explanatory text to the documentation.
Remember, once a user understands how your custom program works, the prompts become
less useful to them as they learn the input sequences.
Similar to prompt messages, error messages displayed by a custom program should be short
and right to the point. Longer explanations and steps needed to resolve an encountered
problem should be placed in the documentation, not the custom program itself. Problems
encountered by your custom programs should be handled by one of two types of error
messages: soft and hard. soft error messages provide the user with an indication something
went wrong, but doesn’t interrupt the user’s workflow for the most part and the
command/function continues. hard error messages are displayed prior to the termination of a
command/function and do interrupt the workflow of the user. An example of a soft error
message would be a prompt message at the Command prompt to have the user try a different
value, while an example of a hard error message would be an alert box that the user must
engage with before continuing.
Beyond the prompts and error messages used in a custom program, explanatory and reference
documentation should be provided with your custom programs. The explanatory documentation
can be as simple as a listing of exposed commands with a description of each option available,
to a more comprehensive set of documentation that explains when the user might use a certain
command along with what its benefits might be. The complexity of the documentation and the
desired user experience impacts how you deliver the documentation. You might choose to
deliver the documentation as a/an:
 Set of loose web (HTML, JS, CSS) and image files
 Compiled Help (CHM) file
 WinHelp (HLP) file

Page 3
While your documentation should be accessible from outside of the AutoCAD-based program,
integrating it into the usage of your custom programs makes the experience more fluid and feel
like an extension of the AutoCAD-based program. The AutoLISP programming language
provides several functions that can be used to hook up your custom programs to the AutoCAD
Help system. These AutoLISP functions can be used to display custom help:
 HELP – Displays a file in the native help window or a topic from a CHM/HLP file in its
respective application window
 SETFUNHELP – Associates a file or topic from a CHM/HLP file to a command; the
file or topic is then displayed contextually in the native help window or its respective
application window when F1 is pressed from the AutoCAD user interface
 STARTAPP – Launches an application with or without a specified file; can be used to
open file formats that are not supported by the HELP and SETFUNHELP functions
Along with the previously mentioned functions, plug-in bundles can be used to associate custom
help topics to each exposed command in a custom program. Plug-in bundles are covered
under the section “Build Plug-in Bundles for AutoLISP Programs” later in this handout.
Note: The examples in this section can be found in the 2 - help setfunhelp and startapp.lsp file
that is part of the dataset associated with this session.

Display a help file/topic with the HELP function


The HELP function is used to display a file that contains information about the functionality
exposed in a custom program, typically this would be the main topic in a documentation set.
You can display an HTML, CHM, or HLP file with the HELP function.
Note: While you are limited to HTML, CHM, and HLP files with the HELP function, it is possible
to display a TXT or PDF file using an HTML page that performs a redirect. An example of this
can be found in the 2 - TXTRedirect.html and 2 - PDFRedirect.html files that are part of the
dataset for this session.
The syntax of the HELP function is:
(help [help_file [chm_hlp_topic [chm_help_window_command]]])
The following examples demonstrate how to call help from inside AutoCAD-based products:

;; Displays the LINE command topic from the AutoCAD help system
(help "" "LINE")

;; Displays a Web page


(help "http://www.hyperpics.com/")

;; Displays a local HTML file


(help "C:\\Program Files\\Autodesk\\AutoCAD 2017
Help\\English\\Help\\index.html")

;; Displays a CHM file


(help "C:\\Program Files\\Common Files\\Autodesk Shared\\en-
US\\acadauto.chm" "IDH_LINE_OBJECT")

Page 4
Display a help file/topic with the SETFUNHELP function
The SETFUNHELP function is used to associate a help file that contains information related to a
specific command/function exposed by a custom program, typically this would be a topic within
a documentation set but could be a stand-alone file. You can display an HTML, CHM, or HLP
file with the SETFUNHELP function. Once the command/function is defined and the help file
has been associated, you can display the topic by pressing F1 under the following situations:
 When AutoComplete is enabled and the full name of the command is displayed, but
the command has not been started yet
 When the command is active
Note: While you are limited to HTML, CHM, and HLP files with the SETFUNHELP function, it is
possible to display a TXT or PDF file using an HTML page that performs a redirect. An example
of this can be found in the 2 - TXTRedirect.html and 2 - PDFRedirect.html files that are part of
the dataset for this session.
The syntax for the SETFUNHELP function is:
(setfunhelp c:function_name [help_file [chm_hlp_topic
[chm_help_window_command]]])
The following examples demonstrate how to set up contextual/F1 help for custom commands:

;; Displays the LINE command topic from the AutoCAD help system
(defun c:CMD1 () (getstring "\nEnter some text: "))
(setfunhelp "c:CMD1"
""
"LINE")

;; Displays a Web page


(defun c:CMD2 () (getstring "\nEnter some text: "))
(setfunhelp "c:CMD2"
"http://www.hyperpics.com/")

;; Displays a local HTML file


(defun c:CMD3 () (getstring "\nEnter some text: "))
(setfunhelp "c:CMD3"
"C:\\Program Files\\Autodesk\\AutoCAD 2017
Help\\English\\Help\\index.html")

;; Displays a CHM file


(defun c:CMD4 () (getstring "\nEnter some text: "))
(setfunhelp "c:CMD4"
"C:\\Program Files\\Common Files\\Autodesk
Shared\\en-US\\acadauto.chm"
"IDH_LINE_OBJECT")

Page 5
Display a file with the STARTAPP function
While the STARTAPP function is not designed for displaying help, it can be used as an
alternative to the HELP function. The STARTAPP function is used to launch an application and
open a document. While it is possible to only open an HTML, CHM, or HLP file with the HELP
and SETFUNHELP functions, you can open the following file types using various applications
with the STARTAPP function and more:
 ASCII text (TXT) file
 Rich Text Format (RTF) file
 Microsoft Word (DOC/DOCx) document file
 Portable Document Format (PDF) file
The syntax for the SETFUNHELP function is:
(setfunhelp c:function_name [help_file [chm_hlp_topic
[chm_help_window_command]]])
The following examples demonstrate how to open various document types that could contain
help content:

;; Displays a text (TXT) file


(startapp "notepad"
"\" C:\\Program Files\\Autodesk\\AutoCAD 2017\\
en-US\\timesrvr.txt\"")

;; Displays a Rich Text Format (RTF) file


(startapp "write"
"\"C:\\Program Files\\Autodesk\\AutoCAD 2017\\
Support\\AcCopyrights.rtf\"")

;; Displays a Word (DOC/DOCx) document file


(startapp "C:\\Program Files\\Microsoft Office
15\\root\\office15\\WINWORD.EXE"
"\"C:\\Datasets\\SD20507\\
SD20507-Ambrosius-AU2016.docx\"")

;; Displays a Portable Document Format (PDF) file


(startapp "C:\\Program Files (x86)\\Adobe\\Reader 11.0\\
Reader\\AcroRd32.exe"
"\"C:\\Datasets\\SD20507\\
SD20507-Ambrosius-AU2016.pdf\"")

Creating a CHM file


A CHM file is a compiled file that contains HTM/HTML and image files along with any resource
(JS and CSS) files required to properly display the content in the HTM/HTML files. No
specialized editor is needed to create HTM/HTML files, you can use a simple ASCII text editor,
such as Notepad on Windows or TextEdit on Mac OS. However, a specialized editor such as
Hot Dog or Dreamweaver can make the task of formatting and editing HTM/HTML files much
easier though. Even Microsoft Word can be used to create and edit HTM/HTML files, but it
does sneak in additional content that isn’t necessary though.

Page 6
Once the HTM/HTML files have been authored, the files can then be added to a CHM project
file using Microsoft HTML Help Workshop (http://www.microsoft.com/en-
us/download/details.aspx?id=21138) which is free, or a specialized content
managing/publishing software such as Adobe RoboHelp
(http://www.adobe.com/products/robohelp.html) and MadCap Flare
(http://www.madcapsoftware.com/products/flare/).
The following steps outline how to create a CHM file using HTML Help Workshop.
1. In Windows, do one of the following:
a. Windows 7: Click the Windows Start button  All Programs  HTML Help
Workshop  HTML Help Workshop.
b. Windows 8: On the Windows Start screen, right-click and click All Apps. Scroll to
the HTML Help Workshop section and click HTML Help Workshop.
c. Windows 8.1: On the Windows Start screen, click All Apps located near the
lower-left corner of the screen. Scroll to the HTML Help Workshop section and
click HTML Help Workshop.
d. Windows 10: Click the Windows Start button  All Apps  HTML Help
Workshop  HTML Help Workshop.
2. In the HTML Help Workshop window, click File  New.
3. In the New dialog box, select Project and click OK.
4. In the New Project Wizard, click Next.
5. In the New Project Wizard, Destination page, click Browse.
6. In the Open dialog box, browse to Documents (or My Documents) and enter the name
AU2016. Click Open.
7. In the New Project Wizard, Destination page, click Next.
8. In the New Project Wizard, Existing Files page, click Next.
9. In the New Project Wizard, Finish page, click Finish.
The following steps outline how to modify the properties of the project (HPP) file and add HTM
files to the project.
1. In the HTML Help Workshop window, Project tab, click Change Project Options.
2. In the Options dialog box, click in the Title field and enter AU 2016 Sample Help.
3. Click OK.
4. In the HTML Help Workshop window, Project tab, click Add/Remove Topic Files.
5. In the Topic Files dialog box, click Add.
6. In the Open dialog box, browse to and select the Topic1.htm, Topic2.htm, and
Topic3.htm files that are part of the dataset for this session. Click Open.
7. In the Topic Files dialog box, click OK.
8. In the HTML Help Workshop window, click File  Save Project.
The following steps outline how to create a TOC for the help project.
1. In the HTML Help Workshop window, click the Contents tab.

Page 7
2. In the Table of Contents Not Specified dialog box, choose Create A New Contents File
and click OK.
3. In the Save As dialog box, browse to the location of the help project file and click Save.
4. In the HTML Help Workshop window, Contents tab, click Insert A Page.
5. In the Table of Contents Entry dialog box, General tab, click in the Entry Title text box
and enter Topic 1.
6. Click Add.
7. In the Path or URL dialog box, under HTML Titles, select Topic 1 and click OK.
8. Click OK.
9. In the HTML Help Workshop window, Contents tab, select Topic 1.
10. Click Insert A Page.
11. If the HTML Help Workshop message box is displayed, click No.
12. In the Table of Contents Entry dialog box, General tab, click in the Entry Title text box
and enter Topic 2.
13. Click Add.
14. In the Path or URL dialog box, under HTML Titles, select Topic 2 and click OK.
15. Click OK.
16. Select Topic 2 and click Move Selection Right.
17. In the HTML Help Workshop window, Contents tab, select Topic 2.
18. Click Insert A Page.
19. If the HTML Help Workshop message box is displayed, click No.
20. In the Table of Contents Entry dialog box, General tab, click in the Entry Title text box
and enter Topic 3.
21. Click Add.
22. In the Path or URL dialog box, under HTML Titles, select Topic 3 and click OK.
23. Click OK.
24. In the HTML Help Workshop window, Contents tab, select Topic 2.
25. Click Move Selection Right.
26. In the HTML Help Workshop message box, click Yes.
27. In the HTML Help Workshop window, click File  Save Project.
The following steps outline how to add index entries to the help project.
1. In the HTML Help Workshop window, click the Index tab.
2. In the Index Not Specified dialog box, choose Create A New Index File and click OK.
3. In the Save As dialog box, browse to the location of the help project file and click Save.
4. In the HTML Help Workshop window, Index tab, click Insert A Keyword.

Page 8
5. In the Table of Contents Entry dialog box, General tab, click in the Keyword text box and
enter Main.
6. Click Add.
7. In the Path or URL dialog box, under HTML Titles, select Topic 1 and click OK.
8. Click OK.
9. Click Insert A Keyword.
10. If the HTML Help Workshop message box is displayed, click No.
11. In the Table of Contents Entry dialog box, General tab, click in the Keyword text box and
enter Sub, Topic 1.
12. Click Add.
13. In the Path or URL dialog box, under HTML Titles, select Topic 2 and click OK.
14. Click OK.
15. Click Insert A Keyword.
16. In the Table of Contents Entry dialog box, General tab, click in the Keyword text box and
enter Sub, Topic 2.
17. Click Add.
18. In the Path or URL dialog box, under HTML Titles, select Topic 3 and click OK.
19. Click OK.
20. In the HTML Help Workshop window, click File  Save Project.
The following steps outline how to compile and view the help project.
1. In the HTML Help Workshop window, click File  Compile.
2. In the Create A Compiled File dialog box, click Compile.
3. In Windows Explorer or File Explorer, browse to the location of the compiled CHM file.
4. Double-click the compiled CHM file.
5. Click through the items on the Contents and Index tabs.

3 Support Multiple Languages


The landscape of design firms has been changing over the past decade from being regional to
more global. Working with groups around the world has its own challenges; time zone
differences, skillsets, and local knowledge along with spoken/written language. Time zone and
local knowledge are not something that most developers need to be concerned with, but need to
be aware of for support reasons. Skillset can toss a monkey wrench into things when trying to
training or deploy a set of custom programs, but doesn’t necessarily impact the development of
a custom program too much. Spoken/written language on the other hand is something that you
might need to be concerned with as you develop custom programs. While writing everything in
your native language makes things easier for you, it might not be as welcoming to another
group of users halfway across the globe.

Page 9
Most AutoLISP programs these days are not sold, but rather are used by end users within the
company they were originally developed or migrated with users when they switched companies.
Since most AutoLISP programs are not sold, they are written originally to work in a single
version of an AutoCAD-based product. For example, a program written for the English
language version of AutoCAD might not work correctly in the French language version of
AutoCAD. This isn’t done intentionally, but rather it wasn’t something most in-house developers
worried much about. The failure of the program doesn’t even address the issue of localized
prompt and error messages along with documentation.
The following are items could affect the deployment of your custom programs when supporting
multiple languages:
 Use of the COMMAND function; commands and options need to use global syntax
 Definition of custom commands with the DEFUN function
 Macros assigned to user interface elements in a partially loaded CUI/CUIx file
 Prompt strings, keywords, and error messages
 Dialog boxes implemented using DCL
 Documentation used to support the custom programs

Proper syntax of commands and options with the COMMAND function


Command names and the option names within a command vary based on the installed
language of the AutoCAD-based product being used. For example, the LINE command is what
a user might type if they were using the English version of AutoCAD, but for French users the
LINE command is actually named LIGNE. These differences in command names can greatly
affect how AutoLISP programs are executed within an AutoCAD-based product.
The English version of the product doesn’t understand the command LIGNE and the French
version doesn’t understand the command LINE without some help. The LINE and LINGE
commands are referred to as local command names; command names are specific to a give
language version. All, well most, commands defined as part of the standard AutoCAD product
have two different names; a local command name and what is known as a global command
name.
A global command name is a universal name given to a command that is the same across all
languages of the product, and in most cases it is always the English command name with an
underscore in front of it. If you are using a language version of the AutoCAD product other than
English, you can identify the global name of a command with the AutoLISP GETCNAME
function.
The following examples show the results of using the GETCNAME function in the English and
French versions of AutoCAD 2017:
;; AutoCAD 2017 – English
Command: (getcname "LINE")
"_LINE"
Command: (getcname "LIGNE")
nil

;; AutoCAD 2017 – French


Commande: (getcname "LINE")
nil

Page 10
Commande: (getcname "LIGNE")
"_LINE"
Notice the _ (underscore) character that is returned in front of the _LINE value, the underscore
is used to let the AutoCAD program know you want to use a global command name instead of
the local command name. What is interesting about the GETCNAME function is that you can
pass the function a global command name and get the local command name back.
;; AutoCAD 2017 – English
Command: (getcname "_LINE")
"LINE"

;; AutoCAD 2017 – French


Commande: (getcname "_LINE")
"LIGNE"
Just like command names, the options within a command also commonly have local and global
names. The global name of an option is the one that appears in the English language prompt of
a command. However, unlike with commands, there is no easy way to identify the global name
for an option.
Tip: If you don’t already have the English language pack installed for your AutoCAD-based
product, I recommend you installing it to not only test your custom programs but to get the
English name of the options in your custom programs.
The following example doesn’t work in both the English and French versions of AutoCAD:
(command "LINE" "0,0" "5,5" "5,0" "C")
In the French version of AutoCAD, you would see the following in the Command Line window:
LINE Commande inconnue "LINE". Appuyez sur F1 pour obtenir de
l'aide.
Commande: 0,0 Commande inconnue "0,0". Appuyez sur F1 pour
obtenir de l'aide.
Commande: 5,5 Commande inconnue "5,5". Appuyez sur F1 pour
obtenir de l'aide.
Commande: 5,0 Commande inconnue "5,0". Appuyez sur F1 pour
obtenir de l'aide.
Commande: C Commande inconnue "C". Appuyez sur F1 pour obtenir
de l'aide.
Commande: nil
The correct syntax for the statement would be as follows:
(command "_LINE" "0,0" "5,5" "5,0" "_C")
By just adding the _ (underscore) in front of the command and option names, the AutoLISP
statement is processed correctly in both versions. The following shows the output in the
Command Line windows for both products:
Command: (command "_LINE" "0,0" "5,5" "5,0" "_C")
_LINE
Specify first point: 0,0
Specify next point or [Undo]: 5,5
Specify next point or [Undo]: 5,0
Specify next point or [Close/Undo]: _C

Page 11
Commande: (command "_LINE" "0,0" "5,5" "5,0" "_C")
_LINE
Spécifiez le premier point: 0,0
Spécifiez le point suivant ou [annUler]: 5,5
Spécifiez le point suivant ou [annUler]: 5,0
Spécifiez le point suivant ou [Clore/annUler]: _C

Define custom functions that support local and global names


Now that you know how to access global command and option names for the commands that
are defined in the AutoCAD product, what about those that you create with AutoLISP?
AutoLISP functions defined with the DEFUN function don’t mimic the behavior of AutoCAD
commands; unlike AutoCAD commands, an AutoLISP function can’t be defined with separate
local and global command names without some help. For example, an AutoLISP function
defined with the symbol name C:EVALUATE can be started by typing EVALUATE or
_EVALUATE at the Command prompt.
There are two approaches that can be used to support global and local commands, and they
are:
 Use the DEFUN function to define both an English and localized command name
when supporting more than the English language
 Use the VLAX-ADD-CMD function to define a local and true global command name
for an AutoLISP function
Note: The examples in this section can be found in the 3 - defun and vlax-add-cmd example.lsp
file that is part of the dataset associated with this session.

Use DEFUN to define local and global commands


By using the DEFUN function to define both an English and localized command name when
supporting more than the English language, you support not only a global name through the
English definition of the function, but also a local name for your users in their written language.
The user wouldn’t need to enter _ (underscore) at the Command prompt or Dynamic Input
tooltip first to use the pseudo global command name in this situation because you would always
be registering the English command name. This approach does expose additional commands
to AutoComplete that you might not want the user to see, but it does allow for the support of
global names across custom menus, scripts, action macros, and more.
For example, for your English language custom programs you would only provide and register
the English commands:
; Local command name for English
(defun c:Evaluate ( / )
(alert "Command started.")
)
; The user can enter
; EVALUATE or _EVALUATE
When supporting a language such as French, your French language custom programs provide
and register the English and French commands:
; Local command name for English
(defun c:Evaluate ( / )
(alert "Command started.")

Page 12
)
; Local command name for French
(defun c:Evaluer ( / )
(alert "Commande a commencé.")
)
; The user can enter
; EVALUATE or _EVALUATE
; EVALUER or _EVALUER
Note: Defining a command with a _ (underscore) might seem like a logical approach to
supporting global command names, but it doesn’t actually work that way. Command names
can’t start with an underscore, so the following approach is NOT valid:

; Local command name for French


(defun c:Evaluer ( / )
(alert "Commande a commencé.")
)
; Global command name for French (not needed for English release)
(defun c:_Evaluate ( / )
(alert "Command started.")
)

Use VLAX-ADD-CMD to define local and global commands


The VLAX-ADD-CMD function can be used to define a global and local command name for an
AutoLISP function. The global and local command names don’t need to be the same, which is
different from the way global and local command names are defined with the DEFUN function.
The global command names defined with this approach work just like native AutoCAD
commands, the user must type a _ (underscore) in front of the global command name at the
Command prompt or Dynamic Input tooltip to access it. Unlike the approach mentioned
previously with the DEFUN function, you don’t need to expose the English version of a
command along with a localized command which keeps things more natural.
Tip: Unlike commands defined with the DEFUN function, commands defined with VLAX-ADD-
CMD can be used with the COMMAND function
The syntax for the VLAX-ADD-CMD function is:
(vlax-add-cmd global-name func-sym [local-name [cmd-flags]])
The following example demonstrates how to define a global and localized command:

; Global and local command name for English version


(defun Evaluate ( / )
(alert "Command started.")
)
(vlax-add-cmd "evaluate" 'evaluate "evaluate")

; Global and local command name for French version


(defun Evaluate ( / )
(alert "Commande a commencé.")
)
(vlax-add-cmd "evaluate" 'evaluate "evaluer")

Page 13
The AutoLISP function passed to the VLAX-ADD-CMD function can begin with the c: prefix, but
it is recommended to not define your functions with the prefix for those you plan on registering
as commands with the VLAX-ADD-CMD function. Defining a function with the c: prefix
registers the function as a local command in the language version, which isn’t always the
desired outcome.
For example, in the French language version, if you register an AutoLISP function named
C:EVALUATE with the VLAX-ADD-CMD function, the end user can directly type EVALUATE
and EVALUER at the Command prompt. The ideal situation would be to only have EVALUATE
accessible as a global command name by prefixing a _ (underscore) in front of the name.
Note: While you typically don’t need to worry about unregistering a command, it is possible to
reverse the process of the VLAX-ADD-CMD function. The VLAX-REMOVE-CMD function
unregisters the global and local command names for an AutoLISP function that was registered
using the VLAX-ADD-CMD function. The VLAX-REMOVE-CMD function expects a global
command name.
The following example unregisters the global and local command names associated with the
global command name EVALUATE:
;; Undefine/unregister a global and local command
(vlax-remove-cmd "evaluate")

Translate content between languages


Supporting users in their native written language can take time to plan and execute, but if done
it can improve the experience of your users. While it is always best to be able to speak the
languages you plan on supporting, that isn’t as important as it once was with the invention and
improvements in machine translation. Machine translation is a service that automatically
converts text written in English or another language, and translates it to a target language of
interest.
The following are a few machine translation services that might be helpful:
 BableFish - https://www.babelfish.com/
 Bing Translator - http://www.bing.com/Translator
 Microsoft Office Translator - https://support.office.com/en-us/article/Translate-text-in-
a-different-language-287380E4-A56C-48A1-9977-F2DCA89CE93F
 Google Translate - https://translate.google.com/
Tip: When using machine translation, translate a string from English to the target language and
then try and convert the string returned for the target language back into English to see if it
makes sense. You might need to go back and forth to clean up the text strings being translated
to ensure they are meaningfully. The English language does have some strange writing
conventions at times, such as contractions, conjunctions, and gerunds which you might want to
avoid when possible. For that reason, it can at times be better to write text strings in a language
other than English, such as French or Spanish, and translate those into English.
Machine translation can be a low cost solution, but does work best with having an actual person
review the content for grammar and accuracy. Consider the following, based on your available
budget and resources (items are ranked in order of cost):
 Internal staff that reads both English and the target language.

Page 14
 Students or professors from a local college or university who are studying or
teaching a foreign language. Those individuals might be willing to review the content
that was translated using an online service and make the necessary corrections, or
even manually perform the translations for a combination of pay and/or work
experience.
 External company that specializes in the language translation.

Display localized prompt and error messages


Once the prompt and error messages to be displayed in your custom programs have been
translated by machine translation or a live individual, there are several approaches that can be
used to display the translated messages in your custom programs. The following are the
approaches that can be utilized to store localized text strings:
 Create separate versions of your custom programs, one for each language. This
approach can be seen in the Support folder under the AutoCAD install directory. The
English versions of the files are stored in an en-US folder, while those for the French
version are stored in an fr-FR folder.
 Define variables or functions in an AutoLISP file to hold or return the localized strings,
and then recall those string values as needed. All possible string values are stored in a
single version of the custom programs.
 Store the localized strings in a text or XML file, and read those strings into your custom
programs as needed. This is a hybrid solution of the two previous approaches, and is
the approach commonly used by ObjectARX and Managed .NET applications that utilize
resource files with string tables. By storing the strings externally from your custom
programs, it makes the process to localize the strings much easier.
The last two approaches could have an impact on performance based on the number of
messages being displayed and how the values are stored in memory. Whether the impact is
noticeable depends greatly on hardware and the frequency in which the strings are accessed.
Based on workstations today, there might be no noticeable or measurable performance lose.
Note: While creating separate versions of your custom programs for each supported language
might take the least amount of effort in the short term, since your programs don’t need to be
modified, it could lead to additional work in the future when trying to resolve bugs, testing the
programs, and introducing new functionality. If you do consider creating separate files to
support different languages, consider writing an application that automatically updates the
translated strings in each custom program. By automating the string updates, it lowers the risk
of introducing errors in the programs and still allows you to work from a single source code
base.

Identify product language


No matter which approach you decide is best for you to support multiple languages, the
language version of the AutoCAD-based product being used must be identified in order to load
the correct version of a program or display the proper localized strings. AutoCAD has what is
referred to as a product key which is used to identify the AutoCAD-based program; plain vanilla
AutoCAD or a vertical based product along with language version. The product key is stored in
the Windows Registry and can be used to identify the current language version of the product
being executed.

Page 15
The product key of the current AutoCAD-based product can be obtained with the VLAX-
PRODUCT-KEY function. The last characters of the string returned by VLAX-PRODUCT-KEY
can be used to identify the language version of the product. For example, the value “409”
indicates the English version of the product is being used, while a value of “40C” indicates the
French version.
Note: The LOCALE system variable is related to language support, but at the operating system
level. You can use the LOCALE system variable to identify the locale info of the operating
system, is AutoCAD installed on an English or French version of Windows. The value assigned
to the LOCALE system variable is a three character string.
The following examples show the value returned by the VLAX-PRODUCT-KEY function in the
English and French versions of AutoCAD:
;; AutoCAD 2017 – English
Command: (vlax-product-key)
"Software\\Autodesk\\AutoCAD\\R21.0\\ACAD-0001:409"

;; AutoCAD 2017 – French


Commande: (vlax-product-key)
"Software\\Autodesk\\AutoCAD\\R21.0\\ACAD-0001:40C"
Tip: As previously mentioned, the product key can be used to identify if the AutoCAD-based
product is vanilla AutoCAD or a vertical product. 0001 indicates the product is vanilla AutoCAD,
whereas a value of 0007 would indicate AutoCAD Electrical is the product being used.
The custom function named returnLanguageCode returns the last three letters of the
product key for the current AutoCAD-based product. The definition of the
returnLanguageCode function is as follows:
;; Returns the three letter language code from the product key
;; Usage: (returnLanguageCode)
(defun returnLanguageCode ( / )
(strcase
(substr (vlax-product-key)
(- (strlen (vlax-product-key)) 2)
)
)
)
Note: The examples in this section can be found in the 3 - localize text string example.lsp file
that is part of the dataset associated with this session.

Page 16
Access and display text strings based on language
As I previously mentioned, there are several different approaches to storing and displaying text
strings based on the language version of AutoCAD being used. The following is just one
approach which utilizes lists to store and organize translated strings.
The custom function named returnLocalizedString returns a translated text string
based on the current language version of the product; English or French. Each of the translated
strings that can be returned are stored in a list of dotted pairs. The function expects two strings,
program name and resource ID.
 programName – Used to access strings stored in the function for a specific
command or utility. The program name is used as a way to organize the strings for
multiple applications.
 resourceID – Used to get a specific string from the list.
The definition of the returnLocalizedString function is as follows:
;; Helper function that returns a resource string
;; based on language code
;; Usage: (returnLocalizedString "SAMPLE" 3)
(defun returnLocalizedString (programName resourceID /
languageCode)

;; Get the language code for the current product


(setq languageCode (returnLanguageCode))

;; Get a text string based on program name and


;; resource ID from the list
(cond ((= (strcase programName) "SAMPLE")
(cond ((= languageCode "409") ; English text strings
(cdr (assoc resourceID '(
(1 . "ABC")
(2 . "One")
(3 . "White")
(4 . "XYZ")
)
))
)
((= languageCode "40C") ; French text strings
(cdr (assoc resourceID '(
(1 . "ABC")
(2 . "Un")
(3 . "Blanc")
(4 . "XYZ")
)
))
)
)
)
)
)
;; AutoCAD 2017 – English

Page 17
Command: (returnLocalizedString "sample" 3)
"White"

;; AutoCAD 2017 – French


Command: (returnLocalizedString "sample" 3)
"Blanc"
Tip: Plug-in bundles, discussed under the section “Build Plug-in Bundles for AutoLISP
Programs” later in the handouts, can be used to load a specific language version of a custom
program or specify a support folder that contains the resource files needed for the language
version of the product being used.
Note: The examples in this section can be found in the 3 - localize text string example.lsp file
that is part of the dataset associated with this session.

Support global and local keywords in custom functions


Keywords, like commands, can be defined to support both global and local names. The
INITGET function is used to setup the keywords which represent the options of a command.
The keywords for a user input function are defined by creating a space-delimited string, each
grouping of characters represents a single option. The character groups often contain a mix of
upper and lowercase characters which represent the value a user must enter to choose the
option.
For example, the following defines a list of keywords that represent color values in English and
French:
; English keywords
"Blue White Red Green"
; French keywords
"blEu blAnc Rouge Vert"
By default, local and global keyword names are the same. You can specify different global and
local keyword names as part of the INITGET function by adding a space after the last local
keyword name and a _ (underscore) in front of the first global keyword name. A global keyword
name must be provided for each local keyword name, and typically the global keyword names
are the same as the keywords used for the English language version.
The syntax for the INITGET function is:
(initget [bits] [keywords [_localKeywords]])
The following examples demonstrate how to define a set of keywords with global and local
names:
;; English keywords example
(initget "Blue White Red Green _Blue White Red Green")
(getkword "\nSpecify color [Blue/White/Red/Green]: ")

;; French keywords example


(initget "blEu blAnc Rouge Vert _Blue White Red Green")
(getkword "\nSpécifiez la couleur [blEu/blAnc/Rouge/Vert]: ")
In both the previous examples, entering B, Blue, E, Bleu, _Blue, or _B all return a value of
“Blue”. _Blue and _B are both valid values that can be entered to specify the color Blue in the
English and French examples. By providing global keyword names, it allows you and end users

Page 18
to reliably create custom scripts and action macros, and use the commands you expose in
macros for custom user interface elements. From a programming stand point-of-view, you only
need to worry about handling the return of the global keyword names and not both global and
local keyword names.
The following shows the previous example statements used in a function named
PromptForKeyword:
;; Returns the three letter language code from the product key
(defun returnLanguageCode ( / )
(strcase
(substr (vlax-product-key)
(- (strlen (vlax-product-key)) 2)
)
)
)

; Main function body


(defun PromptForKeyword (/ languageCode keywords promptMsg)
(setq languageCode (returnLanguageCode))

;; Get the keywords and prompt message based on language


(cond ((= languageCode "409")
(setq keywords "Blue White Red Green
_Blue White Red Green"
promptMsg "\nSpecify a color
[Blue/White/Red/Green]: "
)
)
((= languageCode "40C")
(setq keywords "blEu blAnc Rouge Vert
_Blue White Red Green"
promptMsg
"\nSpécifier une couleur
[blEu/blAnc/Rouge/Vert]: "
)
)
)

;; Request input from the user


(initget keywords)
(setq kWordRetVal (strcase (getkword promptMsg)))

;; Display the global keyword name


(alert kWordRetVal)
)

;; Define a global and local commands based on language code


(cond ((= (returnLanguageCode) "409")
(vlax-add-cmd "PromptForKeyword" 'PromptForKeyword
"PromptForKeyword")
)

Page 19
((= (returnLanguageCode) "40C")
(vlax-add-cmd "PromptForKeyword" 'PromptForKeyword
"InvitePourMotcle")
)
)
; English example - works
(command "_promptforkeyword" "B")
; French example - fails
(command "_promptforkeyword" "B")
; French example - works
(command "_promptforkeyword" "_B")
Note: The examples in this section can be found in the 3 - initget.lsp file that is part of the
dataset associated with this session.

Create global macros to use in CUI/CUIx files for multiple languages


Just like with the COMMAND function, macros created for and assigned to user interface
elements in a CUI/CUIx file should utilize both global command and option names. This is done
by adding a _ (underscore) in front of the English language command and option names.
If you look at the macro for the Circle, Center, Diameter command in the English version of the
CUI/CUIx file or Cercle, Centre, Diamètre command in the French version of the CUI/CUIx file,
you will see that the macro is the same in both CUI/CUIx files. The macros include the use of a
_ (underscore) in front of the CIRCLE command and Diameter (d) option names. Using this
approach reduces the amount of testing need when supporting custom user interfaces as part of
your custom programs.
The following shows the macro assigned to the Circle, Center, Diameter and Cercle, Centre,
Diamètre commands:
^C^C_circle \_d

4 Deploy and Load AutoLISP Program Files


Before custom programs can be used, they must be moved from the development environment
to where an end user will be able to load them; this process is known as deployment. The
following questions can be used to help you determine the best deployment process to use:
 Where the custom programs will be stored and loaded from; local or network drive?
 Who will be using the custom programs; internal or external users?
 What is the expertise level of the users?
Custom programs can be deployed by:
 Manually copying the program and resource files to a local or network drive; this
method can be used to deploy programs internally and externally to users, but could
result in more problems than creating an installer.
 Automating the copying of program and resource files from a network location to a
local drive with a Group Policy or script/batch file; this method is often used when
deploying programs internally to a large number of users at a company. Remote file

Page 20
sharing such as Box, DropBox, and Google can be good alternatives to share files
with remote employees.
 Creating an installer that handles the copying of files to a computer; this method is
often used when deploying programs to external companies, and can be the most
effective way to deploy programs. There are many different programs on the market
to create an installer, most have a cost associated with them. I have personally used
InstallShield (http://www.flexerasoftware.com/producer/products/software-
installation/installshield-software-installer/) which starts at $699 for Express and up
for the higher-end products, and Setup projects available in Visual Studio
Professional and higher.
Tip: The MS-DOS XCOPY command and RoboCopy utility can make it easy to synchronize
files on a local drive with those stored on a remote/network drive. RoboCopy can be download
as part of the Windows Server 2003 Resource Kit (http://www.microsoft.com/en-
us/download/details.aspx?id=17657) along with its companion utility Robocopy GUI at
https://technet.microsoft.com/en-us/library/2006.11.utilityspotlight.aspx.
After the program and resource files have been deployed to a local or network drive, the
program files can then be loaded into an AutoCAD-based product. The following outlines the
methods that can be used to load a program into an AutoCAD-based product:
 Manually with the APPLOAD command (Load/Unload Application dialog box);
requires users to load the custom program files each time they are needed.
 Automatically using the Startup Suite of the APPLOAD command; requires users to
add each custom program file to the Startup Suite, but only needs to be done once.
 Automatically using the acad.lsp or acaddoc.lsp program files; the files must be
created and placed in a support file search path and trusted location, but the problem
with this approach is that an end user might already have these files on their
computer loading other AutoLISP programs.
 Automatically using a CUI/CUIx file; add the LSP files to be loaded under the LSP
Files node of a loaded CUI/CUIx file. This is done by using the Customize User
Interface (CUI) Editor.
 Automatically using a MNL file with the same name as a custom CUIx file that is
loaded as either a full customization file or a partial customization file. The MNL file
must have the same name as the CUI/CUIx file; for example, mytools.cuix and
mytools.mnl.
 Automatically using a plug-in bundle; a plug-in bundle can be used to configure the
AutoCAD drawing environment and load AutoLISP programs when a drawing is
opened or created. Along with loading program files with a plug-in bundle, it is
possible to partially load a CUIx file as well.
Note: You can centralize the loading of multiple AutoLISP programs by defining a single
AutoLISP program file that end users load, this single program file the loads all other AutoLISP
files with the use of the LOAD function or loads the files on-demand when a command in that file
is used. The AutoLISP AUTOLOAD function is used to load an AutoLISP program file on-
demand when a command is used the first time. In addition to the AUTOLOAD function, a plug-
in bundle can also be used to automatically load an AutoLISP program file when a command is
used the first time.

Page 21
While having end users manually load program files can make deployment tasks easier for you,
it can be very problematic for them and lead to a support nightmare for you if something goes
wrong. No matter if you have your end users manually load the program files or if the files are
automatically loaded, you need to consider the following questions:
 How will the end user specify the necessary support file search paths and trusted
locations to load and use your custom program and resource files? See “Specify
Support File Search Paths” and “Trust Executable Locations” for more information.
 Should the source code contained in your custom program files be protected? See
“Compile and Protect AutoLISP Files” for more information.
 Should the custom program files be digitally signed? See “Digitally Signing
AutoLISP Program Files” for more information.
Plug-in bundles make it fairly easy to deploy AutoLISP programs as you just need to distribute a
folder structure and the files contained in them. The folder structure organizes and contains all
the program and resource files needed, along with the information required to configure the
AutoCAD drawing environment. You can learn more about plug-in bundles under the “Build
Plug-in Bundles for AutoLISP Programs” section later in this handout.

5 Specify Support File Search Paths


Support file search paths are critical in letting the AutoCAD program know where your custom
program files are located along with any resource files that your custom programs might be
dependent upon. Resource files might be ASCII text files that store localized text strings or
other data, drawing files that contain block definitions among other files. By specifying support
file search paths, you don’t need to use absolute paths in your custom programs. Absolute
paths make your programs harder to manage in different environments. Chances are you
already specify support file search paths as part of your current deployments so the AutoCAD
program can locate your files correctly.
You can specify support file search paths using these methods:
 Options dialog box, Files tab; user profile can then be exported and imported on
other workstations
 ACAD environment variable, not a system variable, which can be modified using an
AutoLISP program
 AutoCAD.AcadPreferencesFiles.SupportPath property in the AutoCAD
ActiveX library which can be accessed using an AutoLISP program
 AutoCAD installation deployment
 Plug-in bundle

Add a support path with the Options dialog box


The following explains how to add a folder to the AutoCAD support file search path using the
Options dialog box:
1. In AutoCAD, at the Command prompt, enter options.
2. In the Options dialog box, Files tab, select the Support File Search Path node.
3. Click Add and then click Browse.

Page 22
4. In the Browse for Folder dialog box, browse to and select the folder which contains
your custom programs and resource files.
5. Click OK to append the selected folder.
6. Optionally, add any additional folders that might be needed.
7. Click OK to save the changes and exit the Options dialog box.

Add a support path with the ACAD environment variable


The following outlines how to add a folder to the AutoCAD support file search path using the
ACAD environment variable:
1. In AutoCAD, at the Command prompt, enter (setq curACADPaths (getenv
"ACAD")).
Note: The name of an environment variable is case sensitive, "ACAD is not the
same as "acad".
2. At the Command prompt, enter (setenv "ACAD" (strcat curACADPaths
"<yourPathHere>" ";")).
Replace the text "<yourPathHere>" with the folder you want to add, such as
"c:\\abc_corp_settings".
Note: When the value of the ACAD environment variable is changed, the AutoCAD
program validates all of the folders. If a folder being appended doesn’t exist or a
duplicate folder is being added, the value is updated to remove the folder under both
situations.
The following AutoLISP function wraps the previous steps and validates the folder being
appended:
;; Usage (appendSupportPath "c:\\my programs")
(defun appendSupportPath (folderName / curACADPaths)
(if (vl-file-directory-p folderName)
(progn
(setq curACADPaths (getenv "ACAD"))
(setenv "ACAD" (strcat curACADPaths folderName ";"))
)
)
)
The following shows how to append a folder to the support file search paths using ActiveX:
(defun appendSupportPathX (folderName / acPrefFilesObj
curACADPaths)
(if (vl-file-directory-p folderName)
(progn
;; Get the PreferencesFiles Object
(setq acPrefFilesObj
(vla-get-Files (vla-get-Preferences
(vlax-get-acad-object))))

;; Get the current SupportPath value


(setq curACADPaths (vla-get-SupportPath acPrefFilesObj))

Page 23
;; Append the new folder
(vla-put-SupportPath acPrefFilesObj
(strcat curACADPaths ";" folderName))
)
)
)
Note: The examples in this section can be found in the 5 - support paths.lsp file that is part of
the dataset associated with this session.

6 Trust Executable Locations


Trusted locations are not an Autodesk only concept, but one that has been pushed by operating
system developers such as Microsoft and Apple for many years now. A trusted location is
basically a secure location in which applications (also referred to as executables) can be loaded
from into memory and then executed, these locations are typically read-only and might require
administrative rights to modify. For example, on Windows, folders such as Program Files,
Windows, and even the root drive are classified as trusted locations as they don’t allow users to
create or modify files in these locations without special/elevated rights, such as administrator.
These files and file types are considered by the AutoCAD program as executables:
 ARX, DBX, CRX, HDI files
 LSP, FAS, VLX, MNL, SCR files
 .NET assemblies
 VBA macros (DVB files)
 acad.rx
 JavaScript
 DLL files
Starting with AutoCAD 2013 SP1, trusted locations were introduced as part of a series of
security changes made to the release in order to help protect companies from the rise in
malware and the theft of intellectual property. The introduction of trusted locations was done to
limit the loading of files that might not be approved or obtained from an unknown publisher.
There are two types of trusted locations: inherited and user.
Inherited trusted locations are defined by the operating system or AutoCAD-based product, for
the most part on Windows and Mac OS those locations are:
 Windows – C:\Program Files\ and C:\Program Files (x86)\ along with their
subfolders
 Mac OS – ~\Applications along with its subfolders

Page 24
In addition to the locations that are inherited or automatically trusted, you can specify other
trusted locations that might be on your local or network drive. Any locations that you manually
add should be read-only, otherwise it defeats the purpose of using trusted locations as a
security feature since the files could be manipulated by an external program to load and execute
malware within the AutoCAD program. You can specify additional trusted locations by using
one of these methods:
 Options dialog box, Files tab; user profile can then be exported and imported on
other workstations
 TRUSTEDPATHS system variable
 AutoCAD installation deployment
Note: Custom programs must also be listed in a folder identified as a Support File Search Path
in order for the AutoCAD program to locate the files that can be loaded.
While trusted locations are optional, it is recommended to ensure your applications work
correctly under this environment and participate in this ecosystem to help reduce the risk in
which users might be exposed to malware. Even though the trusted locations feature can be
disabled or softened with the SECURELOAD system variable, it is recommended to never turn
the feature off; especially if you are releasing custom programs to external companies.
If a custom program or user attempts to load a custom program file from outside of a trusted
location, a task dialog box is displayed and it warns the user that the file doesn’t come from a
trusted source. The name of the custom program file and its location from which it is being
loaded is displayed to help the user determine whether it is safe.

Page 25
The message displayed does vary slightly based on the type of file being loaded and whether it
has been digitally signed.

Note: While it is possible to disable the use of trusted locations, it is recommended not to. As a
programmer, you should make sure your programs work correctly with SECURELOAD enabled
or disabled.

Trust subfolders
By default, the subfolders in a trusted location are not trusted. To trust the subfolders under a
trusted location, you must append the text \.. to the end of the location. When you append the
text \.. to a trusted location, the location is no longer trusted but the subfolders are trusted.
For example:
C:\My Programs\LSPs – Applications in the LSPs folder are trusted, but not those in
the subfolders
C:\My Programs\LSPs\.. – Applications in the subfolders of the LSPs folder are
trusted, but not those in the LSPs folder

Add a trusted location with the Options dialog box


The following explains how to specify a folder as a trusted location using the Options dialog box:
1. In AutoCAD, at the Command prompt, enter options.
2. In the Options dialog box, Files tab, select the Trusted Locations node.
3. Click Add and then click Browse.
4. In the Browse for Folder dialog box, browse to and select the folder which contains
the applications to trust.

Page 26
5. Click OK.
6. If the Trusted File Search Path – Security Concern message box is displayed, click
Continue.
This dialog box warns that the location is not read-only, it is recommended to
mark the location as read-only.
7. Optionally, add any additional folders that might need to be trusted.
8. Click OK.

Add a trusted location with the TRUSTEDPATHS system variable


The following explains how to add a trusted location using the TRUSTEDPATHS system
variable:
1. In AutoCAD, at the Command prompt, enter trustedpaths.
2. At the Command prompt, in the dynamic tooltip, type a ; (semi-colon) and then the
new trusted location.
Note: Each location must be separated by a semi-colon.
3. Press Enter.
Note: If a location is added to the TRUSTEDPATHS system variable more than once,
AutoCAD doesn’t remove the duplicate location entries.
The following AutoLISP example demonstrates how to add trusted locations to the
TRUSTEDPATHS system variables and ensure duplicate locations are not added.
;; Usage (appendTrustedLocation "C:\\My Programs\\LSPs")
;; Usage (appendTrustedLocation "C:\\My Programs\\LSPs\\..")
(defun appendTrustedLocation (folderName / curTrustedPaths)
(setq curTrustedPaths (getvar "trustedpaths"))

(if (vl-file-directory-p folderName)


(progn
(if (not (vl-string-search
(strcase (strcat folderName ";"))
(strcase curTrustedPaths)))
(if (not (vl-string-search (strcase folderName)
(strcase curTrustedPaths)))
(if (/= curTrustedPaths "")
(setq curTrustedPaths (strcat curTrustedPaths
";" folderName))
(setq curTrustedPaths folderName)
)
)
)
(setvar "trustedpaths" curTrustedPaths)
)
)
)

Page 27
Note: The examples in this section can be found in the 6 - trusted locations.lsp file that is part of
the dataset associated with this session.

7 Compile and Protect AutoLISP Files


AutoLISP code, unlike many other programming languages, doesn’t need to be compiled before
it is deployed. However, AutoLISP programs can be optionally compiled or protected to help
secure and deter changes being made to the source code.
While there have been a number of different ways to restrict access to AutoLISP source code,
there are three main utilities that developers choose to use which are as follows:
 Kelvinate (kelv.exe) – Utility that removes whitespace and comments from an
AutoLISP source file, and mangles symbol (function and variable) names. A file
modified using kelv.exe, can still be read after prettifying the file and studying the
mangled symbols.
 Protect (protect.exe) – Utility that performs a basic level of encryption on an
AutoLISP source file. Typically, you would run kelv.exe on a source file first and then
protect.exe. Protecting a file does deter non-programmers from making changes,
but if you know how to protect a source file, there is a pretty good chance you might
know how to unprotect a file with a free utility that was protected using protect.exe.
 Visual LISP IDE – Development environment that ships with an AutoCAD-based
product on Windows and can be used to not only edit and manage AutoLISP source
files, but compile them into FAS and/or VLX files. VLX files can contain multiple
AutoLISP source/compiled files along with resources files such as TXT or DCL files.
Note: Both kelv.exe and protect.exe can still be found on the Internet if you look hard enough,
but for the most part these are obsolete utilities and should no longer be used. It is
recommended to compile/protect files using the Visual LISP IDE whenever possible. I mention
the two programs here because they do come up in conversations from time to time with older
programmers and those that might not be aware of using the Visual LISP IDE to protect
AutoLISP source files.

Page 28
Compile AutoLISP source files with Visual LISP
The following explains how to compile an AutoLISP program file into a FAS and VLX file:
1. In AutoCAD, on the ribbon, click Manage tab  Applications panel  Visual LISP Editor.
2. In the Visual LISP Editor, click File menu  Make Application  New Application Wizard.
3. In the Application Wizard, on the Wizard Mode page, select Simple and click Next.

Select Expert if you want to include DCL, TXT, and other resource files for your custom
programs in the compiled application.
4. On the Application Directory page, click Browse.
5. In the Browse for Folder dialog box, browse to and select the folder in which the FAS
and VLX files should be output when the AutoLISP source file is compiled.
6. Click in the Application Name text box and type the name of the application you want to
build. Typically, it is the same name as the AutoLISP source file to be compiled.

7. Click Next.

Page 29
8. On the LISP Files to Include page, click Add.
9. In the Add Lisp Source Files dialog box, browse to and select the AutoLISP source file to
compile. Click Open.

10. Click Next.


11. On the Review Selections / Build Application page, make sure Build Application is
checked and click Finish.
The FAS file generated can be deployed to users of AutoCAD-based products on
Windows or Mac, but VLX files can only be deployed to users on Windows.
12. In Windows Explorer or File Explorer, browse to the folder chosen for the build output.
The messages are displayed in the Visual LISP Console and <Build Output> windows
about the files that are compiled.

Page 30
8 Digitally Sign AutoLISP Program Files
Digital signatures are blocks of encrypted information that are often applied to program files by a
software vendor (also referred to as a publisher) to inform an end user whether a program file
has been modified after it was released. While a digital signature lets a user know if a program
file has been modified after it was signed, it doesn’t indicate whether the program file is safe to
load. When loading a program file, you should make sure the file was signed by a reputable
software vendor and that the digital signature is valid.
Note: Support for digitally signed program files is limited to AutoCAD 2016-based products and
later, and the Windows platform. Digital signatures are placed in comment blocks, so loading a
digitally signed program file in an AutoCAD 2015-based product or earlier shouldn’t cause any
problems.
While digital signatures are optional, it is recommended to digitally sign your custom programs
files if and when possible. As previously mentioned, it doesn’t ensure that the file is safe, but it
will help users identify whether a program file has been compromised by malware or someone
else that has access to your workstation.
Files that have been previously digitally signed can be identified in Windows Explorer or File
Explorer by a small badge displayed on the file icon.

The following types of program files can be digitally signed and loaded into an AutoCAD-based
product:
 ARX, CRX, DBX
 DLL, EXE
 FAS, LSP, MNL, VLX
 HDI

Obtain a digital certificate (ID)


Prior to being able to digitally sign a program file, you need to obtain a digital certificate (also
referred to as a digital ID). Digital certificates are commonly obtained from a Certificate
Authority (CA) which is a company (also referred to as a Trust Service Provider) that manages
and maintains a database of public and private keys that are used to apply a digital signature to
a program file. There are many CAs that a digital certificate can be purchased from, some of
the more common ones are:
 DocuSign - https://www.arx.com/Digital-Signatures-trial/registration-new.php
 Comodo - https://www.comodo.com/home/email-security/free-email-certificate.php
 GlobalSign - https://www.globalsign.com/en/secure-email/
 IdenTrust - https://www.identrust.com/certificates/trustid.html

Page 31
Note: The digital certificates by IdenTrust were previously managed by GeoTrust and Symantec
(https://www.identrust.com/symantec/smime/index.html).
Digital certificates are not free, the cost varies based on the CA and the type of certificate you
need. If you are a software developer, you might want to obtain a Code Signing Certificate
which can be $300+ versus a Personal Authentication Certificate (PACs) that is around $20.
It is possible to make a digital certificate using the MakeCert.exe tool that is part of the Windows
SDK. The MakeCert.exe tool can be obtained from Microsoft's website at
http://msdn.microsoft.com/en-us/library/bfsktky3(v=vs.110).aspx. For the actual steps on
creating a digital certificate, search for the topic “To Make a Digital Certificate” in the AutoCAD
Online Help system (http://bit.ly/2e7IFCr). While you can make a digital certificate on your local
machine for testing purposes, you will still want to obtain a digital certificate from a CA before
distributing any signed application files. The CA holds a copy of the digital certificate so the
user can validate the signature attached to a program file.

Digitally sign an AutoLISP (LSP) source file


AutoLISP (LSP) source files can be digitally signed using the Attach Digital Signature utility that
ships with AutoCAD 2016-based products and later.
1. In Windows, do one of the following:
 Windows 7: Click the Windows Start button  All Programs  Autodesk
<product name>  Attach Digital Signatures.
 Windows 8: On the Windows Start screen, right-click and click All Apps. Scroll to
the Autodesk section and click <product name>  Attach Digital Signatures.
 Windows 8.1: On the Windows Start screen, click All Apps located near the
lower-left corner of the screen. Scroll to the Autodesk section and click <product
name>  Attach Digital Signatures.
 Windows 10: Click the Windows Start button  All Apps  Autodesk  Attach
Digital Signatures.
2. In the Attach Digital Signatures dialog box, click Add Files.
3. In the Select File dialog box, browse to and select the LSP file to digitally sign. Click
Open.
Note: As a reminder, you can digitally sign FAS, VLX, and MNL files as well which can
contain custom programs developed with the AutoLISP programming language.
4. Optionally, add files from other folders as needed.
5. Under the Select a Digital ID (Certificate) section, choose the digital certificate to use.
6. Optionally, choose a resource from which the current time can be obtained for the time
stamp and enter a comment to be attached to the files being signed.
Tip: You can specify a different server for obtaining the current time by modifying the
timesrvr.txt which can be found in the C:\Program Files\Autodesk\AutoCAD 2017\en-US
folder. If you are using a different language version, substitute the folder en-US for the
appropriate folder of that language, such as fr-FR for French.
7. Click Sign Files.
8. If the file being signed is read-only, click Sign This File Anyway to continue and sign the
file, or click Skip This File to not digitally sign the read-only file.

Page 32
9. If the file being signed was previously signed, click Replace The Existing Signature to
overwrite the previous signature, or click Skip This File to not digitally sign the file.
10. In the Signing Complete message box, click OK to continue.
11. In the Attach Digital Signatures dialog box, click Close to exit the dialog box.
Note: If you need to digitally sign a Managed .NET DLL or ObjectARX application file, see the
topic “To Digitally Sign a Binary (ObjectARX or Managed .NET) File” in the AutoCAD Online
Help system (http://bit.ly/2ds1wcd).

Verify a digital signature


The following explains how to validate a digitally signed file:
1. In Windows Explorer or File Explorer, select the digitally signed file to validate.
2. Right-click the selected file and choose Properties.
3. In the Properties dialog box, click the Digital Signature tab.
The information on the tab indicates the software vendor that signed the file and
whether the digital signature is valid.

4. When done reviewing the information associated with the digital signature, click OK
or Cancel.

9 Build Plug-in Bundles for AutoLISP Programs


Plug-in bundles are a relatively new and overlooked concept by many individuals that create
AutoLISP programs to extend the functionality of AutoCAD-based products. Introduced with
AutoCAD 2013-based products, plug-in bundles were developed as a way to deliver custom
programs from the AutoCAD Exchange store or deploy custom programs without first needing to

Page 33
post them to the AutoCAD Exchange store. A plug-in bundle is a folder structure with an XML
manifest file that describes the organization of the files and their roles in the plug-in bundle to an
AutoCAD-based product. The name of the root folder for a plug-in bundle must end with
.bundle, and the XML manifest file for the plug-in bundle must have the name
PackageContents.xml and be located in the root folder.
Along with specifying the files that make up a plug-in bundle, the PackageContents.xml file can
also define:
 Information about a plug-in bundle; name, description, version, author and more
 Supported products and versions; OS, AutoCAD product platform, minimum and
maximum product release
 Component entries (files) of the application; name, description, type, load reason and
per document
 Commands; global and local names, help topics, and commands to execute at
startup
The most basic reason to create a plug-in bundle is to load one or more custom program files
when a drawing file is created or opened in the AutoCAD drawing environment, and to partially
load a customization file that contains user interface (UI) elements related to the custom
programs that the plug-in bundle loads. In addition to being able to indicate which custom
program and customization files should be loaded into an AutoCAD-based product, a plug-in
bundle can also set and modify:
 Support file search paths
 Tool palette paths
 Registry key values
 System and environment variable values
Plug-in bundles help to solve the issue of needing to manually modify settings in the AutoCAD
drawing environment to load custom programs. Most deployments of LSP files include
modifying the Startup Suite of the Load/Unload Applications dialog box or adding AutoLISP load
function statements to either the acad.lsp or acaddoc.lsp files along with specifying where the
support files for the custom programs exist.
Specifics about the XML syntax and elements that make up a PackageContents.xml file can be
found in the AutoCAD Help system by searching on the text “packagecontents.xml format
reference” (http://bit.ly/2ed6195).

Support multiple platforms, releases, and operating systems


One of the largest benefits to plug-in bundles is how they can be used to restrict the loading of
custom program files into a specific release of an AutoCAD-based product, and control which
components are loaded by operating system. Many of these restrictions are handled with the
RuntimeRequirements element in a PackageContents.xml file. The RuntimeRequirements
element supports these attributes:
 OS – Controls which operating systems the plug-in supports; “Win32” – Windows
32-bit, “Win64” – Windows 64-bit, and “Mac” – Intel 64-bit Mac OS
 SeriesMin – Minimum AutoCAD-based release that is supported; 19.0 and later
including minor revision numbers (19.1, 19.2, …)

Page 34
 SeriesMax – Maximum AutoCAD-based release that is supported; 19.0 and later
including minor revision numbers (19.1, 19.2, …)
 Platform – Controls which AutoCAD-based products the plug-in bundle supports;
“AutoCAD*” indicates AutoCAD and all AutoCAD-based vertical products are
supported
The following RuntimeRequirements element example indicates that the components in the
plug-in bundle are supported on Windows 32- and 64-bit, but not Mac OS and only supported
for AutoCAD 2015 and AutoCAD 2016.
<RuntimeRequirements
OS="Win32|Win64"
SeriesMin="R19.0"
Platform="AutoCAD*"
SupportPath="./ENU/Resources"
SupportPathFra="./FRA/Resources"
/>
Note: If no SeriesMax attribute is provided, the maximum release is every release after the
minimum release.
For information on all the allowable values by attribute, see the “RuntimeRequirements Element
Reference” (http://bit.ly/2eiuECO) topic in the AutoCAD Online Help system.

Support multiple languages


Plug-in bundles were designed to simplify the deployment of custom programs that support
multiple languages. Many of the attributes within the elements defined in the
PackageContents.xml file support what is known as a locale suffix. A locale suffix is a case-
sensitive three letter code used to identify a value or module for use with a specific language
version of an AutoCAD-based product. For example, the attribute ModuleName specifies a file
that should be loaded in English versions and all language versions that don’t have a
corresponding attribute with an appended locale suffix, such as ModuleNameFra which
specifies a file to be loaded in French language versions of the product.
The following ApplicationPackage and ComponentEntry element examples show how to support
multiple languages; English and French. The English description and modules will be used for
all languages except French.
<ApplicationPackage
SchemaVersion="1.0"
AppVersion="1.0"
Name="AU2016 SD20507"
Description="AU2016 Example for session SD20507."
DescriptionFRA="AU2016 exemple de session SD20507."
Author="Lee Ambrosius"
Icon="./Resources/AU2016_samp.png"
HelpFile="./ENU/Help/AU2016.chm"
HelpFileFra="./FRA/Help/AU2016.chm"
ProductCode="{45F619FE-E286-4C4E-8134-B50E8DFC23E3}"
>

<ComponentEntry Description="Core custom file"


AppName="AU2016Examples"

Page 35
Version="1.0"
ModuleName="./ENU/au2016.lsp"
ModuleNameFra="./FRA/au2016.lsp" >
</ComponentEntry>

Reminder: Locale suffixes are case-sensitive, FRA is NOT the same as Fra.
For a full list of supported locale suffixes, see the “Supported Locale Codes Reference”
(http://bit.ly/2ejamsP) topic in the AutoCAD Online Help system.
Along with specifying localized general properties and modules in a plug-in bundle with the
ApplicationPackage and ComponentEntry elements, it is possible to associate a help topic to a
local or global command based on language version. The following example shows how to use
the Commands and Command elements to associate a help and/or a specific help topic to the
global command names TAGBUBBLE, P3, and TB. A command can be registered with the
VLAX-ADD-CMD or DEFUN function. The topics in this example are part of the AU2016.chm
file assigned to the HelpFile attribute of the ApplicationPackage element. If you want more
control over which help file is associated to a command, you will want to use the SETFUNHELP
function in the AutoLISP program files in which the commands are defined.
<ComponentEntry Description="Additional examples"
AppName="AU2016AdditionalExamples"
Version="1.0"
ModuleName="./ENU/au2016ex.lsp"
ModuleNameFra="./FRA/au2016ex.lsp" >

<Commands GroupName="AU2016_SAMPLE">
<Command Global="TagBubble"
HelpTopic="Topic2"
Description="Creates a tag bubble"
DescriptionFra="Crée une bulle de balise" />
<Command Global="P3"
HelpTopic="Topic3" />
<Command Global="TB" />
</Commands>
</ComponentEntry>
If you assign a HTM/HTML file to the HelpFile attribute of the ApplicationPackage element, you
have some extra work to do if you want to display a different help topic for each command. The
URL opened when the user presses F1 contains the path to the HTM/HTML file assigned to the
HelpFile attribute and a parameter named contextId. The contextId parameter is follow4ed by
the value assigned to the HelpTopic attribute of the command. The following is an example of
the URL that is opened:
file:///C:/ProgramData/Autodesk/ApplicationPlugins/SD20507.bundle/
FRA/Help/index.html?contextId=Topic2.htm
The following is an example of an index.html file that does a basic parse of the URL for a
context Id and performs a redirect to the designated topic when a context Id is provided:
<!DOCTYPE html>
<html>
<head>
<title>HELP</title>

Page 36
<script type="text/javascript">
var URL = window.location.href;
var base = URL.split("?")[0];
var contextID = URL.split("=")[1];
if (contextID) {
window.location = base.replace("index.html", contextID);
}
</script>
</head>
<body>
<p>*REPLACE* - This main file shows how to do a redirect to a
specific topic when a valid context ID is provided.</p>
</body>
</html>
Here is an example of a plug-in bundle that utilizes HTM/HTML files instead of a CHM file for
help documentation:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationPackage
SchemaVersion="1.0"
AppVersion="1.0"
Name="AU2016 SD20507"
Description="AU2016 Example for session SD20507."
DescriptionFRA="AU2016 exemple de session SD20507."
Author="Lee Ambrosius"
Icon="./Resources/AU2016_samp.png"
HelpFile="./ENU/Help/index.html"
HelpFileFra="./FRA/Help/index.html"
ProductCode="{45F619FE-E286-4C4E-8134-B50E8DFC23E3}"
>

<CompanyDetails
Name="HyperPics, LLC"
Url="http://www.hyperpics.com"
/>

<Components Description="Windows and Mac OS operating systems">


<RuntimeRequirements
OS="Win32|Win64|Mac"
SeriesMin="R19.0"
Platform="AutoCAD*"
SupportPath="./ENU/Resources"
SupportPathFra="./FRA/Resources"
/>

<ComponentEntry Description="Core custom file"


AppName="AU2016Examples"
Version="1.0"
ModuleName="./ENU/au2016.lsp"
ModuleNameFra="./FRA/au2016.lsp" >
</ComponentEntry>

Page 37
<ComponentEntry Description="Additional examples"
AppName="AU2016AdditionalExamples"
Version="1.0"
ModuleName="./ENU/au2016ex.lsp"
ModuleNameFra="./FRA/au2016ex.lsp" >

<Commands GroupName="AU2016_SAMPLE">
<Command Global="TagBubble"
HelpTopic="Topic2.htm"
Description="Creates a tag bubble"
DescriptionFra="Crée une bulle de balise" />
<Command Global="P3"
HelpTopic="Topic3.htm" />
<Command Global="TB" />
</Commands>
</ComponentEntry>
</Components>
</ApplicationPackage>

Example of a basic plug-in bundle


The following is what the folder structure might look like for a basic plug-in named
SD20507.bundle:
SD20507.bundle
|-> au2016.lsp
|-> b-tblk.dwg
|-> PackageContents.xml
The PackageContents.xml file in SD20507.bundle might look similar to the following example:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationPackage
SchemaVersion="1.0"
AppVersion="1.0"
Name="AU2016 SD20507"
Description="AU2016 example for session SD20507."
Author="HyperPics, LLC"
ProductCode="{C3FC64FD-0FDD-4130-94CF-BB75A00733A9}"
>

<CompanyDetails
Name="HyperPics, LLC"
Url="http://www.hyperpics.com"
/>

<Components Description="Windows and Mac OS operating systems">


<RuntimeRequirements
OS="Win32|Win64|Mac"
SeriesMin="R19.0"
Platform="AutoCAD*"
/>
<ComponentEntry Description="Your custom file"

Page 38
AppName="AU2016Examples"
Version="1.0"
ModuleName="./au2016.lsp">
</ComponentEntry>
</Components>
</ApplicationPackage>
Note: The ProductCode value must be unique for each bundle that AutoCAD loads. You can
generate a GUID value by using the Online GUID Generator website
(http://www.guidgenerator.com/).

Deploy a plug-in bundle


After a plug-in bundle has been defined, it must be copied to one of the following locations for
testing or deployment:
All Users Profile folder
 Windows 7, Windows 8, and Windows 10:
%ALLUSERSPROFILE%\Autodesk\ApplicationPlugins
 Mac OS: /Applications/Autodesk/ApplicationAddins
User Profile folder
 Windows 7, Windows 8, and Windows 10:
%APPDATA%\Autodesk\ApplicationPlugins
 Mac OS: ~/Autodesk/ApplicationAddins
Plug-in bundles are loaded into an AutoCAD-based product at startup or during a set interval
based on the value of the APPAUTOLOAD system variable. The AutoCAD-based products and
releases in which the plug-in bundle can be loaded are determined by the values in the
PackageContents.xml file. By default, the APPAUTOLOAD system variable is set to a value of
14 which loads a plug-in bundle at startup, when a new drawing is created, and when the plug-
in bundle is added to the plug-ins folder.
Note: Setting the APPAUTOLOAD system variable to a value of 15 will display messages each
time a plug-in bundle is loaded which can be helpful in troubleshooting.

Create a custom plug-in bundle based on sample files


This section explains how to define and deploy a custom plug-in bundle named
SD20507.bundle. Make sure you download and extract the files from the dataset associated
with this session.
In these steps, you learn how to create a plug-in bundle named SD20507.bundle.
1. In AutoCAD, at the Command prompt, type explorer and press Enter.
Windows Explorer or File Explorer can also be started from Windows by doing one of
the following:
 Windows 7: Click the Windows Start button  All Programs  Accessories 
Windows Explorer.
 Windows 8/8.1: On the Windows Start screen, type explorer. In the Search charm,
click File Explorer. You can also right-click in the lower-left corner of the screen and
choose File Explorer.

Page 39
 Windows 10: Click the Windows Start button  All Apps  Accessories  File
Explorer.
2. In Windows Explorer or File Explorer, navigate to the dataset folder for this session.
3. Click New Folder.

4. In the in-place editor, type SD20507.bundle and press Enter.


5. In Windows Explorer or File Explorer, select the au2016.lsp file.
6. Hold down the Ctrl key and select the following files:
 au2016ex.lsp
 b-tblk.dwg
 PackageContents.xml
7. Right-click over one of the selected files and choose Copy.
8. Double-click the SD20507.bundle folder.
9. In the empty folder, right-click and choose Paste.
In these steps, you learn how to deploy the bundle named SD20507.bundle.
1. In Windows Explorer or Files Explorer, go back (or up) one folder so you are in the
root folder of the dataset.
2. Right-click over the SD20507.bundle folder and choose Copy.
3. In Windows Explorer or File Explorer, in the Address bar, type
%ProgramData%\Autodesk and press Enter.
4. Double-click the ApplicationPlugins folder.
5. Right-click in an empty area and choose Paste.
The plug-in bundle is now deployed and ready for AutoCAD to pick up. By
default, the plug-in bundle should be loaded into AutoCAD automatically after
placing it in the folder. If it doesn’t, the value of the APPAUTOLOAD system
variable has been changed from its default value of 14.

Page 40
6. Switch back to AutoCAD.
After about 5-10 seconds, you might see a balloon notification appear that your
bundle has been loaded; it doesn’t remain displayed on-screen for long though.
While the bundle has been loaded, the actual LSP files in the bundle aren’t
loaded.

7. Close and restart AutoCAD.


8. When AutoCAD restarts, create a new drawing.
9. In the Security – Unsigned Executable File dialog box, click Load Once.

This dialog box is displayed to let you know that the file hasn’t been digitally
signed.
10. At the Command prompt, type C2 and press Enter. Specify a point in the drawing
area.
11. Type DLI and press Enter. Specify two points to create the linear dimension.
12. Type ZX and press Enter to zoom to the extents of the drawing.
In these steps, you learn how to update the PackageContents.xml file for the SD20507.bundle.
1. In Windows Explorer or File Explorer, in the SD20507.bundle folder under
%ProgramData%\Autodesk\ApplicationPlugins, right-click the PackageContents.xml
file and choose Open With  Notepad.
2. In Notepad, scroll down to the Components element and add the text in bold:
<Components Description="Windows and Mac OS operating
systems">

Page 41
<RuntimeRequirements
OS="Win32|Win64|Mac"
SeriesMin="R19.0"
Platform="AutoCAD*"
SupportPath="./"
/>
<ComponentEntry Description="Your custom file"
AppName="AU2016Examples"
Version="1.0"
ModuleName="./au2016.lsp">
</ComponentEntry>
<ComponentEntry Description="Additional examples"
AppName="AU2016AdditionalExamples"
Version="1.0"
ModuleName="./au2016ex.lsp">
</ComponentEntry>
</Components>
</ApplicationPackage>
3. In Notepad, on the menu bar, click File menu  Save.
4. Close and restart AutoCAD; any changes to the open drawing can be discarded.
5. In AutoCAD, create a new drawing.
6. Click Load Once for each of the Security – Unsigned Executable File dialog boxes that
are displayed.
7. At the Command prompt, type TB and press Enter.
The title block t-blk should be inserted into the current space; if not, make sure the
location of the drawing file and dataset have been added to the Support File Search
Path. The folder of the dataset should be added as directed by the SupportPath
attribute in the plug-in bundle under the RuntimeRequirements element.
8. Type ZX and press Enter.
9. Type ZP and press Enter.
The previous view is restored.
10. Type TAGBUBBLE and press Enter. Type C and press Enter for the circle bubble and
then press Enter to accept the default text height of 3. Specify the center of the circle
and the end of the leader line.

10 Troubleshoot and Debug AutoLISP Files


Once a custom program leaves the safety of the development environment, strange things can
happen to it. A user might not use the custom program as it was originally intended or the
environment it is executing in is very different from that it was developed, both these conditions
could cause a custom program problems. The troubleshooting and debugging of a custom
program can be a challenge at a time and a large complex subject to cover. Even though it can
be complex, there are several things that can be done to assist in trying to identify problems
with a custom program that is ran outside the development environment.

Page 42
Consider implementing these techniques in the custom programs you develop:
 Debugging and error logging
 Function tracing
 Catching and handling errors
 Grouping changes with undo markers, so changes can be rolled back
The following sections expand on the previously mentioned troubleshooting and debugging
techniques, but for more information on debugging AutoLISP programs see my session
“DV1543 - Going on a Bug Hunt: Debugging and Handling Errors in AutoLISP®”
(http://au.autodesk.com/au-online/classes-on-demand/class-catalog/2013/autocad/dv1543) from
AU 2013.

Debug and log errors


The AutoLISP programming language supports some basic debugging techniques that you can
utilize to help troubleshoot a problem in your custom programs. Echoing messages or the
current value of a variable at specific points in your code can be beneficial to see where a
program might be failing. By looking at the last message and values returned, it will give you an
idea where to start looking for the problem that caused the program to fail.
The following AutoLISP functions can be helpful in providing information to determine where a
program might be failing:
 ALERT – Displays a message box containing a text message.
Syntax: (alert message)
 PRINC – Displays a value assigned to a variable or returned by an expression, or a text
message at the Command prompt or an external file if a file descriptor is provided.
Syntax: (princ [expression [file_descriptor]])
 PROMPT – Displays a text message at the Command prompt.
Syntax: (prompt message)
The messages you might display with the previously mentioned functions could be as basic as
“Here1”, “Here2”, “HereX” or more specific to the operation that is happening in the code, such
as “Starting While loop to modify selected objects” or “Updating DXF data for an object.”
The previously mentioned functions are useful for posting information to the AutoCAD user
interface only with the exception of the PRINC function. In addition to the PRINC function, the
following AutoLISP functions can be used to output information to the Command prompt or an
external log file:
 PRIN1 – Displays a value assigned to a variable or returned by an expression, or a text
message at the Command prompt or an external file if a file descriptor is provided.
Strings containing control characters are expanded.
Syntax: (prin1 [expression [file_descriptor]])
 PRINT – Displays a value assigned to a variable or returned by an expression, or a text
message at the Command prompt or an external file if a file descriptor is provided.
Syntax: (print [expression [file_descriptor]])

Page 43
The following demonstrates how these functions can be used to help debug a program. The
code can be found in the 10 - debug - basic.lsp that is part of the files for this session.
; Load COM environment
(vl-load-com)

; Create a Blue Circle using Visual LISP


(defun c:CreateCircle-VL ( / acadObj docObj spaceObj
cenPoint circObj)
; Create a reference to AutoCAD
(setq acadObj (vlax-get-acad-object))

(princ acadObj)
(terpri)

; Create a reference to the current drawing


(setq docObj (vla-get-activedocument acadObj))

(princ acadObj)
(terpri)
(prompt "Determine current space")
(terpri)

; Get a reference to the current space


(if (= (vla-get-activespace docObj) acModelSpace)
(setq spaceObj (vla-get-modelspace docObj))
(setq spaceObj (vla-get-paperspace docObj))
)

(princ spaceObj)
(terpri)
(prompt "Start object definition")
(terpri)

; Create the center point for the circle


(setq cenPoint (vlax-make-safearray vlax-vbdouble '(0 . 2)))
(vlax-safearray-fill cenPoint '(5.0 5.0 0.0))

(princ cenPoint)
(terpri)

; Create a circle at 5,5 in a radius of 1.75


(setq circObj (vla-addcircle spaceObj cenPoint 1.75))

(princ circObj)
(terpri)

; Change the color of the circle to blue


(vla-put-color circObj 5)

(prompt "End object definition")


(terpri)

Page 44
(princ)
)
Note: The ERRNO system variable can be helpful in identifying the most recent error that
occurred when executing your custom program.
The following is based on a similar set of custom functions that I wrote a number of years ago
as an alternative to using just the PRINC function for debugging my custom programs. By using
a set of custom functions, it allowed me to echo values to the Command prompt, suppress the
echoing at release, or even allow me to run a program in a debug state without the user
knowing as it logs information out to a file. Then as part of the error handler, I could display the
information on-screen or even have it post the log file to a network location that I could
automatically pick up and review.
Note: The code shown can be found in the 10 - debug - custom.lsp file that is part of the data
set for this session.
; Global debugging variables
; *GLOBAL-DEBUG-LOGFILE* - Logfile name and location
; *GLOBAL-DEBUG-LOGGING* - Log enabled
; *GLOBAL-DEBUG-ENABLED* - Enable debugging (T or nil)

; Enable debugging - Example usage (debug-mode 2)


(defun debug-mode (enable / )
(cond
((or (= enable 0)(= enable nil))
(if (= (type *GLOBAL-DEBUG-LOGFILE*) 'FILE)
(progn
(close *GLOBAL-DEBUG-LOGFILE*)
(setq *GLOBAL-DEBUG-LOGFILE* nil)
)
)

(setq *GLOBAL-DEBUG-ENABLED* nil


*GLOBAL-DEBUG-LOGGING* nil
*GLOBAL-DEBUG-LOGFILE* nil)
)
((or (= enable 1)(= enable T))
(setq *GLOBAL-DEBUG-ENABLED* 1 *GLOBAL-DEBUG-LOGGING* 0)
(if (= (type *GLOBAL-DEBUG-LOGFILE*) 'FILE)
(progn
(close *GLOBAL-DEBUG-LOGFILE*)
(setq *GLOBAL-DEBUG-LOGFILE* nil)
)
)
)
((= enable 2)
(setq *GLOBAL-DEBUG-ENABLED* 1 *GLOBAL-DEBUG-LOGGING* 1)
(if (/= (type *GLOBAL-DEBUG-LOGFILE*) 'FILE)
(setq *GLOBAL-DEBUG-LOGFILE* (open (strcat
(getvar "tempprefix") "global-debug.log") "a"))
)
)

Page 45
)
(princ)
)

; Get the current state of debugging


(defun debug-get-enabled ( / )
*GLOBAL-DEBUG-ENABLED*
)

; Get the current logging state


(defun debug-get-logmode ( / )
*GLOBAL-DEBUG-LOGGING*
)

; Get the name of the current log file


(defun debug-get-logfile ( / )
*GLOBAL-DEBUG-LOGFILE*
)

; Debug function that is a wrapper for the functionality


; of the princ and prin1 functions. Feature is turned on or
; off based on the function debug-mode.
; Off, Command prompt echo, or External file write
(defun debug (value / )
(if (debug-get-enabled)
(if (/= (debug-get-logmode) 1)
(progn (princ value)(terpri))
(print value (debug-get-logfile))
)
)
(princ)
)

Function tracing
The AutoLISP functions TRACE and UNTRACE enable and disable the trace flag for a specified
function. When a trace is set for a function, you are notified at the Command prompt or in the
Visual LISP Editor Trace window when the function is used, along with the value that the
function was passed and the return/result of the function. This can be helpful in identifying why
a function might be failing.
The syntax for the TRACE and UNTRACE functions are:
(trace function)
(untrace function)
The following demonstrates the use of the TRACE and UNTRACE functions.
Note: The code shown can be found in the 10 - trace and untrace.lsp file that is part of the
data set for this session.
(defun OddOrEven (cnt / )
(if (= (rem cnt 2) 1)
"ODD"

Page 46
"EVEN"
)
)

(trace OddOrEven)

(defun c:TraceUntrace ( / )
(setq cnt 10)

(while (> cnt 0)


(OddOrEven cnt)

(setq cnt (1- cnt))


)
(princ)
)
The following images show the results of tracing the OddOrEven function in the Command
prompt or Visual LISP Trace window.

Catch errors
For many, myself included for years, catching errors is commonly done using a general error
handler, but a general error handler is kind of like using a sledgehammer for something that
might only need a small nudge. When Visual LISP was first introduced back in AutoCAD 2000,
it came with a new and more elegant way of handling errors right inside of your main function
without utilizing a generic error handling function. The functions that Visual LISP introduced for
catching errors were:

Page 47
 VL-CATCH-ALL-APPLY – Returns the results of a function or an error object that
contains information about the error caused within the function.
Syntax: (vl-catch-all-apply ‘function list)
 VL-CATCH-ALL-ERROR-MESSAGE – Returns a text string based on an error object
returned by the VL-CATCH-ALL-APPLY function.
Syntax: (vl-catch-all-error-message err-object)
 VL-CATCH-ALL-ERROR-P – Identifies if an error object is returned by the VL-CATCH-
ALL-APPLY function.
Syntax: (vl-catch-all-error-p symbol/expression)
The following example demonstrates the use of the VL-CATCH-ALL-APPLY, VL-CATCH-ALL-
ERROR-MESSAGE, and VL-CATCH-ALL-ERROR-P functions.
Note: The code shown can be found in the 10 - catch error.lsp file that is part of the data set
for this session.
; Example shows how to work with the Description property of a
Layer.
(defun c:layerDescription-WithCatch ( / acDoc acLayer acLayers
strLayerName
strLayerDesc)
; Check to see if the Visual LISP ActiveX
; functions have been loaded
(if (/= (type vlax-get-property) 'SUBR)(vl-load-com))

; Get the active drawing and Layers collection


(setq acDoc (vlax-get-property
(vlax-get-acad-object) 'ActiveDocument)
acLayers (vlax-get-property acDoc 'Layers)
)

; Request the name of the layer to modify


(while (/= (setq strLayerName
(getstring T
"\nEnter layer name to add description to: ")) "")

; Check to see if the Layer exists in the drawing


(if (not (vl-catch-all-error-p
(setq err
(vl-catch-all-apply 'vla-item
(list acLayers
strLayerName)))))
(progn
; Layer exists so ask for a description
; to add to the Layer
(setq strLayerDesc
(getstring T "\nEnter description for layer: "))

; If the user just pressed enter then


; remove the description
(if (= strLayerDesc nil)(setq strLayerDesc ""))

Page 48
; Change the Description for the Layer
(vlax-put-property
(vla-item acLayers strLayerName) 'Description
strLayerDesc)
)
(progn
(prompt (strcat "\nerror: "
(vl-catch-all-error-message err)))
(setq strLayerName "")
)
)
)

(princ)
)

Define custom error handlers


In addition to the VL-CATCH-ALL-APPLY function, you can create your own general error
handlers that replace the standard *ERROR* function. The *ERROR* function is called
whenever an error occurs in an AutoLISP function, unless the function is wrapped with the VL-
CATCH-ALL-APPLY function in which an error object is returned instead. When defining a
custom error handler consider the following:
 What was the current state of the drawing before the error?
 Should the changes that were made be kept?
 How the user should be notified about what went wrong?
You use the following functions when defining a custom error handler:
 *ERROR* – User-definable custom error handling function.
Syntax: (*error* string)
 *POP-ERROR-MODE* – Ends the previous call to the *PUSH-ERROR-USING-COMMAND*
or *PUSH-ERROR-USING-STACK* function.
Syntax: (*pop-error-mode*)
 *PUSH-ERROR-USING-COMMAND* – Indicates the use of the COMMAND function within a
custom *ERROR* handler.
Syntax: (*push-error-using-command*)
 *PUSH-ERROR-USING-STACK* – Indicates the use of the COMMAND-S function within a
custom *ERROR* handler.
Syntax: (*push-error-using-stack*)
The following functions demonstrate the use of the previously mentioned functions.
Note: The code shown can be found in the 10 - error handling.lsp file that is part of the data
set for this session.
; Define the values of some global variables
(setq *gVar1* "Global1"
*gVar2* "Global2")

Page 49
; Custom error handler for utility function
; Utilizes the command-s function.
(defun err_sub (msg)
(if (/= msg "Function cancelled")
(prompt (strcat "\nError: " msg
"\nUtilVar1: " *gVar1*
"\nUtilVar2: " *gVar2*)
)
)

(command-s "._undo" "_e")


(command-s "._u")

; Restore previous error handler


(setq *error* old_err)
(princ)
)

; Custom utility function


(defun util (mode / old_err *gVar1* *gVar2*)
; Command-s function being used in custom error handler
(*push-error-using-stack*)

(setq old_err *error*


*error* err_sub)

(command "._undo" "_group")

(setq *gVar1* "Sub1"


*gVar2* "Sub2")

;; Bad code here, get ready for an error if mode is T


(if mode (/ 1 0))

(command "._undo" "_e")

; Restore previous error handler


(setq *error* old_err)

; End using *push-error-using-command*


(*pop-error-mode*)
)

; Custom error handler for main function


; Utilizes the command function.
(defun err_main (msg)
(if (/= msg "Function cancelled")
(prompt (strcat "\nError: " msg
"\nMainVar1: " *gVar1*
"\nMainVar2: " *gVar2*)
)

Page 50
)

(command "._undo" "_e")


(command "._u")

; Restore previous error handler


(setq *error* old_err)
(princ)
)

(defun c:ExampleErrorHandling ( / old_err *gVar1* *gVar2*)


(setq old_err *error*
*error* err_main)

; Command function being used in custom error handler


(*push-error-using-command*)

; Set some local variables


(setq *gVar1* "Local1"
*gVar2* "Local2")

(command "._undo" "_group")

; Call custom function which has some bad code, it T is passed


(util nil)

; Bad code here


(/ 1 0)

(command "._undo" "_e")

; Restore previous error handler


(setq *error* old_err)

; End using *push-error-using-command*


(*pop-error-mode*)
)
If you create your own custom functions that are defined in a separate namespace and built as
part of a VLX file, you might consider using the following functions as well as part of your error
handlers:
 VL-EXIT-WITH-ERROR – Control is passed from a VLX error handler to the *ERROR*
function, and a custom error message is provided to the *ERROR* function.
Syntax: (vl-exit-with-error string)
 VL-EXIT-WITH-VALUE – Control is passed from a VLX error handler to the *ERROR*
function, and a value is provided to the *ERROR* function.
Syntax: (vl-exit-with-value value)
The following examples demonstrate how to use these functions.

Page 51
Note: The code shown can be found in the 10 - VLX-exit-with.lsp and 10 - VLX-exit-with.prv
files that is part of the data set for this session.
(vl-doc-export 'func1)
(defun func1 (val)
;; Custom error handler with exit text
(defun *error* (msg)
(vl-exit-with-error "Oh no!")
)

(prompt (strcat "\nValue: " val))


)

(vl-doc-export 'func2)
(defun func2 (val)

;; Custom error handler with an exit value


(defun *error* (msg)
(vl-exit-with-value 33)
)

(prompt (strcat "\nValue: " val))


)
Note: The AutoLISP functions exit and quit can also be used to exit a custom program.

Establish undo groups to allow rolling back changes


The AutoCAD UNDO command can be very useful when building your own error handler
function, or even as part of your custom programs to ensure all actions performed by it can be
rolled back as a single operation. The BEgin option of the UNDO command allows you to
define when a new group of sequences is to begin and then use the End option to end the
group. Anything inside of that group is rolled back after the AutoCAD U command is called
programmatically or by the user.
The following demonstrates different approaches to creating a custom program that draws two
lines and a circle. If you use the U command after the first example, only the LINE command is
undone, and a second call to the U command is required to undo the CIRCLE command. In the
remaining examples, using the U command undoes both lines and the circle are part of the
same undo group. The final example demonstrates how you might go about implementing a
custom general error handler and how it might close the undo grouping, and even rollback the
changes automatically with the U command.
Note: The code shown can be found in the 10 - undo grouping.lsp file that is part of the data set
for this session.
; Draw two lines and a circle without undo grouping
(defun c:DrawObjects-NoUndoGrouping ( / )
(command "._line" (list 0 0) (list 5 5) (list 0 5) "")
(command "._circle" (getvar "lastpoint") 1)
(princ)
)

; Draw two lines and a circle with undo grouping


(defun c:DrawObjects-UndoGrouping ( / )

Page 52
(command "._undo" "_group")
(command "._line" (list 0 0) (list 5 5) (list 0 5) "")
(command "._circle" (getvar "lastpoint") 1)
(command "._undo" "_e")
(princ)
)

; Draw two lines and a circle with undo grouping, and


; what happens in the case of an error
(defun c:DrawObjects-UndoGroupingNoErr ( / )
(command "._undo" "_group")
(command "._line" (list 0 0) (list 5 5) (list 0 5) "")

; Error caused by not being able to divide by 0


(command "._circle" (getvar "lastpoint") (/ 10 0))
(command "._undo" "_e")
(princ)
)

; Draw two lines and a circle with undo grouping, and


; a custom error handler
(defun c:DrawObjects-UndoGroupingErr ( / old_err)
; Command function being used in custom error handler
(*push-error-using-command*)

; Define custom error handler


(defun my_err_handler (msg)
(if (= (type msg) 'STR)
(if (/= msg "Function cancelled")
(prompt (strcat "\nerror: " msg))
)
)

; Restore previous error handler


(if (/= old_err nil)
(progn
(while (= (getvar "CMDACTIVE") 1)
(command)
)

(command "._undo" "_e")


(command "._u")
(setq *error* old_err)
)
)
(princ)
)

; Define custom error handler


(setq old_err *error*
*error* my_err_handler)

Page 53
(command "._undo" "_be")
(command "._line" (list 0 0) (list 5 5) (list 0 5) "")

; Error caused by not being able to divide by 0


(command "._circle" (getvar "lastpoint") (/ 10 0))
(command "._undo" "_e")

; Restore previous error handler


(if (/= old_err nil)
(setq *error* old_err)
)

; End using *push-error-using-command*


(*pop-error-mode*)
)

Appendix 1 Where to Get More Information


Writing AutoLISP programs is just the beginning to making a group of designers/drafters more
productive. Deploying and supporting your custom programs can be overwhelming at times
based on deadlines and unknown issues that arise. The following resources might prove
beneficial in resolving an issue with a custom program that has been previously deployed or one
that needs to be deployed:
 Help System – The AutoCAD Online Help system contains a lot of information on
creating, managing, and debugging custom programs, working with support file
search paths and trusted locations, digitally signing LSP files, and deploying custom
programs with plug-in bundles.
To access the online help, go to: http://help.autodesk.com/view/ACD/2017/ENU/
 Autodesk Discussion Forums – The Autodesk discussion forums provide peer-to-
peer networking that allows you to ask a question about anything related to AutoCAD
and get a response from a fellow user or Autodesk employee. To access the
Autodesk discussion forums, go to http://forums.autodesk.com, click Browse By
Product near the upper-right of the page and then click AutoCAD. Click the
appropriate subgroup link.
 Autodesk Developer Network (ADN) – If you are a professional programmer or one
that works for a large company, the Autodesk Developer Network can provide you
with training and connect you with Autodesk consultants to help you solve some of
the most difficult programming questions you might have. Visit ADN at
http://www.autodesk.com/developers for more information.
 AUGI Forums – The AUGI forums provide peer-to-peer networking where you can
ask questions about virtually anything in AutoCAD and get a response from a fellow
user. Visit AUGI at http://www.augi.com/ for more information.
 Industry Events and Classes – Industry events such as BIM Workshops and
Autodesk University can be great venues to learn about features in an Autodesk
product and industry trends. Along with industry events, you might also be able to

Page 54
find classes at a local technical college/university or an Autodesk Authorized Training
Center (ATC) that can help you extend your skill set.
 Internet – There are tutorials on the Internet that can be helpful to learn many of the
customization and programming options supported in the AutoCAD program. Use
your favorite search engine, such as Google or Bing and search on the topic of
interest.
 Blogs – There are several AutoCAD bloggers on the Internet that post articles and
best practices for AutoLISP and other programming languages that can be used to
extend AutoCAD. The Autodesk sponsored blogs can be found at:
http://www.autodesk.com/blogs, while my personal blog can be found at
http://hyperpics.blogs.com/.
 Books – There are many general and specialized books that cover AutoCAD
customization and programming. To find a book, use amazon.com or
barnesandnoble.com to locate a book online or visit your local Barnes and Noble
store. My latest book, AutoCAD Platform Customization: User Interface, AutoLISP,
VBA, and Beyond, covers all of the customization options mentioned in this session
and many more.

Page 55

You might also like