This page gets a bit outdated for us at NedCAD because we work hard on a universal autoloader. The longer we use Brixie, the more we love it and I'll give you an illustration:
Application specs for AutoCAD are placed in folder C:\Program Files (x86)\Autodesk\ApplicationPlugins\YourThing\PackageContents.xml. One of the tags is PerDocument=["True"|"False"]. What works: use True for document settings and False for program wide settings. And what does AutoCAD? First do document settings, then start up settings. Document settings need start up settings, so a problem is born. Probably I am stupid and missing a clue but I really don't understand it and given the sparse Autodesk documentation I don't blame myself.
How to solve that? Load document LISP, from there, first thing, load start up LISP, check if a flag says: "if not set, run this code once" and set that flag at "don't run this again". Load document LISP again. vl-bb-set and vl-bb-ref are your companions.
Never mind, here is the article:
Important to state first: AutoCAD does not want to run, execute code in the user environment %AppData%. No LISP there. Just menu's and other things. This means that MyMenu.cuix can be there, but the accompanying MyMenu.mnl with LISP code creates errors, even if you change TRUSTEDPATHS to that location. Signing is an option, but not realistic for an average app.
The AutoLoader concept was introduced in AutoCAD 2014. You put your application in a special directory and AutoCAD loads it. BricsCAD does not know this concept. With AutoCAD 2016, stricter rules are applied. When you are making applications for both BricsCAD and AutoCAD you need a way to work around it. This page aims to help you with that in a clean way.
There is a very short answer: Just install NedCAD's ACME. ACME is an app loader and solves these challenges. More on ACME. Below you'll find some backgrounds.
AutoLoader
The concept is not hard to understand and boils down to the following. Put your AutoCAD LISP code in C:\Program Files (x86)\Autodesk\ApplicationPlugins\YourCode.bundle, include a xml file at that place with additional instructions for AutoCAD and your app gets loaded.
More in detail, the AutoLoader concept is explained here: Autodesk Autoloader White Paper. However, things evolved in time and an explanation of file locations can be found here: AutoCAD 2016: Trusted paths and AutoLoader.
Although the idea behind the AutoLoader mechanism is good, problems can arise when, for example, you put not compiled menu files under the ProgramFiles tree. It is a general rule not to write settings and other data to the ProgramFiles tree. Autodesk suggests to use %appdata% for this.
If you want to code for both CAD systems it is the easiest way to use these file locations for BricsCAD too. However, there is a complication, C:\Program Files (x86)\Autodesk\ApplicationPlugins does not exist in a BricsCAD installation.
Common code for both BricsCAD and AutoCAD
Bricsys really does an impressive job to keep LISP compatible, from time to time it is simply surprising that complex code from AutoCAD LISP runs out of the box from within BricsCAD. And faster too.
Having said this, as your code base grows, it is almost impossible to create common code that is understood by both CAD systems. For example, a path to BricsCAD configuration files differs from a path used in AutoCAD. But that should not keep you from a common code base, you just have to make some T's in your code stream. How is that done? By conditional testing what program is used. On the command line:
(setq vendor (getvar "vendorname"))
Line 1 in BricsCAD, line 2 in AutoCAD:
"Bricsys"
nil
So you can do something like this:
(cond
((= vendor "Bricsys") (princ "\nCode for BricsCAD here... "))
((= vendor nil) (princ "\nCode for AutoCAD here... "))
(T (princ "\nThis beats me... ")))
A clean solution
With all that is written above in mind, there is a clean way to create universal code for both systems.
But first some variables from a standard Windows install.
%USERNAME% = TheUserName
%ProgramFiles% = C:\Program Files
%ProgramFiles(x86)% = C:\Program Files (x86)
%APPDATA% = C:\Users\%USERNAME%\AppData\Roaming
If you need this information in CAD, paste (getenv "username") on the command line for example.
For Linux this does not play since the Autoloader does not exists there. Situation OS-X unknown. This should do it:
%HOME
%USER
The approach can be as follows:
- Put your code in
%ProgramFiles%\Organisation\Product\Version\Code
- Also put your config and writable stuff in
%APPDATA%\Organisation\Product\Version\Config
- For AutoCAD:
- Create an app and put it in
%ProgramFiles(x86)%\Autodesk\ApplicationPlugins\Product.bundle
- This app should put your code and config locations in TRUSTEDPATHS and finally load:
%ProgramFiles%\Organisation\Product\Version\StartWithMe.lsp
- Create an app and put it in
- For BricsCAD:
Put the same StartWithMe.lsp in on_doc_load.lsp:
%ProgramFiles%\Organisation\Product\Version\StartWithMe.lsp
Needless to say, you can put your common code for both BricsCAD and AutoCAD in StartWithMe.lsp
Additional sources
- Trustedpaths can be set in multiple ways. Example:
c:\dir1\dir2;d:\dir3\...;c:\dir4
In this example dir2 and dir4 are trusted while dir3 is trusted plus all directories under dir3. More at this link.
- Some fragments from the LISP file on contents directory as declared in the xml-file:
- Constructing a string for trustedpaths like:
(setq MyAppLoc (strcat (getenv "appdata") "\\YourOrganization\\..."))
- Checking if the string is part of trustedpaths:
(setq TrustedLocs (getvar 'trustedpaths)) (if (not (vl-string-search MyAppLoc TrustedLocs)) (setq TrustedLocs (setvar 'trustedpaths (strcat (vl-string-right-trim ";" TrustedLocs) ";" MyAppLoc))) ) ; More code... (load (strcat (getenv "programfiles") "\\YourOrganization\\MyApp.lsp")) (princ)
- Constructing a string for trustedpaths like: