Jump to content

How to deploy list of Lisps to everyone in the organisation - AutoCAD LT


Recommended Posts

Posted (edited)

Hi,

I work for a civil engineering consultancy and I have created a CUI that will make everyone life easier. The CUI uses some lisp saved on the server and currently I am looking to find ways to deploy these Lisps automatically without the user trying to load them as they are plenty! 

Is there a way that I can deploy all lisp to everyone's AutoCAD LT with minimal input? i.e. maybe a script file to run automatically or tweak something in the AutoCAD settings? Currently in the CUI buttons I have for example ^C^CLISPCOMMAND;  But LT for some reason even after loading all the lisp and selecting always Load seems to forget or ignore that it was previously loaded.

Thank you.

 

I read through some of the previous post, but still unclear how to do it.

Edited by CivilTechSource
Posted

See this discussion at Autodesk. You can put all your LISP code in a file called acaddoc.lsp, and it will automatically load, just like custom linetypes and command aliases.

 

Do they need a copy of that file on each laptop, for instance when they go into the field? Or can you have one copy on a server? That would cut down on overhead.

Posted

LISP is a new addition to LT and it might not do everything you ask, I don't have it so cannot comment on that.

 

If it was me I'd send each user a quick 'how to' guide for the start-up suit in 'appload' asking them to add your LISPs to that. You might only need to have them do that to 1 file which could contain just the below line for each LISP file for you want to auto-load. All these files can be saved in a central location, maintenance is easier - 1 change and they all get it.

 

You could also put the same into the acaddoc.lsp, or get them to open and modify it. Perhaps just the one line to add there as below where LISPFILE.lsp will contain the code to load all your other LISP files. This way you have control in a central location which files to autoload, any changes are just this one file and not everyones acaddoc.lsp file.

 

If you want to be a bit clever with that you can look at opening and editing text files with LISP - which is all acaddoc is - and using LISP append the below line to that file. Send the users a LISP file, they drag it into CAD, it loads (and can run if you include say (....LISP_NAME...) at the end of the file

 

 

Anyway, this line will load a LISP file to the current drawing, you can use that as a basis to load all you want

(load "C://Folder_Location//For_LISPs//LISPFILE.LSP")

 

 

Posted (edited)

Providing you have made a menu and it sits on the server, that will call the lisps. You just need to load that CUIX on each pc. If you add more to that menu, load it so it makes a new CUIX, when a user starts there CAD the latest CUI or CUIX will be loaded.

 

Ok the only other thing you need to do is add the server support paths to each pc. This way you can use just a lisp name not its full path address in your menu. By having all the lisps on the server you control if they are changed or new ones added and always the latest version.

 

Finally I have a setup.lsp it does all the add support paths and load the new menu. So takes like 10 seconds as it sits on the server. Ask if you want more info.

 

Just a comment this menu has some 130 lisps behind it. One of 2 for civil works.

 

menu8.png.87aed6c8a46993749eca5c87f970b1cb.png

 

As suggested we also had some lisps that were autoloaded on startup. Appload "Startup Suite" but we did not load every lisp we had, used the menu for that.

Edited by BIGAL
  • Thanks 1
Posted

Something like this in the acadLTdoc.lsp

 

;;; acadLTdoc.lsp placed on network folder

(setq lispFolder "Z:/Shared/LISP/") ; Change this to your network share path

; Load each LISP file
(load (strcat lispFolder "routine1.lsp"))
(load (strcat lispFolder "routine2.lsp"))
; Add as needed

 

Then you need to updated each users Support File Search Path and Trusted Folders to include the folder for acadLTdoc.lsp

 

Powershell

 

$baseKey = "HKCU:\Software\Autodesk\AutoCAD LT\R24\ACADLT-1001:409\Profiles\<<Unnamed Profile>>\Preferences"
$newPath = "Z:\Shared\CAD\LISP"

# Update Support Path
$supportPath = Get-ItemProperty -Path $baseKey -Name SupportPath
if ($supportPath.SupportPath -notlike "*$newPath*") {
    $updatedSupport = $supportPath.SupportPath + ";" + $newPath
    Set-ItemProperty -Path $baseKey -Name SupportPath -Value $updatedSupport
}

# Update Trusted Paths
$trustedPaths = Get-ItemProperty -Path $baseKey -Name TrustedPaths
if ($trustedPaths.TrustedPaths -notlike "*$newPath*") {
    $updatedTrusted = $trustedPaths.TrustedPaths + ";" + $newPath
    Set-ItemProperty -Path $baseKey -Name TrustedPaths -Value $updatedTrusted
}

 

Or

You can update profiles.

Configure AutoCAD LT on one machine with the correct paths> Export the profile using the OPTIONS > Profiles tab > Export.

Distribute the .arg file and use...

 

"C:\Program Files\Autodesk\AutoCAD LT 2024\acadlt.exe" /p "MyCustomProfile.arg"

 

Or

If preferred you can go direct to Windows registry. (I believe this is correct, but double check) yor IT should know how to do it.

Reg value: SupportPath Type: REG_SZ

Reg value: TrustedPaths Type: REG_SZ

 

C:\Program Files\Autodesk\AutoCAD LT 2024\Support;Z:\Shared\CAD\LISP

 

Or update profiles like this.

 

HKEY_CURRENT_USER\Software\Autodesk\AutoCAD LT\R24\ACADLT-<lang_code>:<product_code>\Profiles\<YourProfileName>\Preferences

 

Your IT may have a deployment software, something above should be what they need for that as well.

  • Like 1
Posted (edited)

A lisp version hope fully works in LT. Change the xxx and path etc.

 

(setq *files*  (vla-get-files  (vla-get-preferences (vlax-get-Acad-object))))
(setq paths (vla-get-SupportPath *files*))
(if (wcmatch  paths "*XXX*")
(princ)
(vla-put-SupportPath *files* (strcat "C:\\XXX-CAD-TOOLS" ";" paths))
)

Copy the 1st two lines to the command line as a test in LT. You should see a list of your support paths

C:\\Users\\XXXX\\AppData\\Roaming\\Bricsys\\BricsCAD\\V25x64\\en_US\\Support;D:\\Bricsys\\BricsCAD V24 en_US\\Support;

 Oh yeah if using Autocad need to add trusted paths, Trusted paths is a bit of why ? As you can set the paths so why have it.

 

(if  (> (vl-string-search  "BricsCAD" (getvar 'acadver)) 0)
(princ "Bricscad") 
(progn
(setq oldtrust (getvar 'trustedpaths))
(if (wcmatch  oldtrust "*XXX*")
(princ)
(setvar 'trustedpaths (strcat oldtrust ";" "c:\\XXX-CAD-TOOLS"))
)
)
)

 

Edited by BIGAL
  • Like 2
  • 2 weeks later...
Posted

Thank you everyone so much!

I decided to go with two options! One will be the CUI button will run a Load command to load the lisp and the call the command. This way only lisp that are required are loaded. However, the reason I was exploring option to load automatically is because some users like to type commands rather than click on Buttons. So I will add one button to the CUI that will run LOAD ALL lisp as per @BIGAL post. This way both users who click or type can have a smooth experience.

Posted (edited)

After your question I resurrected half a script, this one below will search through each .lsp file in folders (folder names are coded in the LISP just for now.. up date as you want), and will create a .lsp file (saved in temporary files folder), opening it to allow you to save it where convenient.

 

The .lsp file created loads on demand .lsp files as and when they are called.

 

If you run this to create a file, that file is all the users need to load when pressing the CUI button - can be quicker loading on demand if you have a lot of / big LISPs that are not all used all the time. If this file is saved in a central location - all users access it - all you need to do is update this 1 file.

 

 

Some failings: 

It is searching for (Defun 123 ( abc / def) at the start of each line.

- If the defun is indented it will skip past it (so as to avoid sub functions which are usually indented)

- If the variable definition (abc / def) is on another line it will cause errors

- If the variable definition is 'nil' (some LISPs do that), then it will also cause errors

- '123' can be for example c:ALisp or MyLisp, doesn't need the 'c' prompt so it picks up utility LISPs common to many LISPs

- File it creates is 0_OpenOnDemand, the '0' is so it loads first, any function that this file creates that is in another file, loaded after, then the file loaded 2nd takes precedence.

Folder paths are entered here twice, once with just a double '\\' and one with a double-double '\\\\' - a fix for later but lazy programming to make it work on a Friday afternoon

 

... needs a little more work to make it a lot more user friendly of course!

 

(defun c:listlisps ( / LispFolder MyLisps MyLispFiles LispList acount fo fn ML n)
;;NOTES:
;;Will fail if the defun lines are not 'ideal': "(Defun abc ( / )" format
;;will fail if variable (global / local) not defined eg defun 'c:abc nil' - wants 'c:abc ( / )'
;;Will fail if subfunctions are not indented
;;Will fail if main functions are indented (won't be found)
;;Filepath is hardcoded


;;Variables
  (setq MyLisps (list))
  (setq OOD_File "0_OpenOnDemand.lsp") ; open on demand file name
  (setq fo (open (setq fn (strcat (getvar "TEMPPREFIX") OOD_File)) "w")) ; create empty OOD_File
  (close fo)

;;LISP Folders
  (setq LispFolderList (list
    "C:\\\\AutoCAD\\\\AutoCAD LISPS" ;;Folder 1
    "C:\\\\AutoCAD\\\\AutoCAD LISPS\\\\Block LISPs" ;; folder 2... can add more
  ))
  (setq MyFolderList (list
    "C:\\AutoCAD\\AutoCAD LISPS" ;;Folder 1
    "C:\\AutoCAD LISPS\\Block LISPs" ;; Folder 2... can add more
  ))

;;while loop from here
  (setq acount 0)
  (while (< acount (length MyFolderList))
    (setq LispFolder (nth acount LispFolderList))
    (setq MyFolder (nth acount MyFolderList))
    (setq MyLispFiles (vl-directory-files MyFolder "*.lsp" 1))
    (vl-remove OOD_File MyLispFiles)
    (setq MyLisps (listlisps MyFolder MyLispFiles))

    (setq fo (open (setq fn (strcat (getvar "TEMPPREFIX") OOD_File)) "a"))
    (foreach ML MyLisps
      (if (or (member OOD_File ML)         ; ignore this file
              (member "SIMPLELISP.lsp" ML) ; ignore this file
          ) ; Endor
        (progn
        )
        (progn
          (foreach n (car (cdr ML))
            (if (wcmatch n "*(*")

;;Change so that zxy(abc / ) -> zxy ( abc / )  - spaces
(write-line (vl-string-subst " " "  " (strcat "(Defun " n " / )")) fo)  ;; if there is a (
(write-line (vl-string-subst " " "  " (strcat "(Defun " n " ( / )")) fo) ;; if there isn't a (. Note might not catch function fully
            ) ; end if
(write-line (vl-string-subst ")" "  )" (strcat "  (Load \"" LispFolder "\\\\" (car ML) "\") (" (vl-string-subst " " "  " (vl-string-subst " " "(" n)) ")(princ)")) fo)
(write-line (strcat ")") fo)


          ) ; end foreach
        ) ; end progn
      ) ; end if
    ) ; end foreach	
    (close fo)
    (setq acount (+ acount 1))
  ) ;  end while
  (startapp "notepad" fn)

  (alert (strcat "Just check this:"
          "\nCheck list file to make sure Defun format is followed"
          "\n <cr>(Defun fnc ( abc / xyz).... with variable definitions"

         )
  )

  (princ)
)

(defun listlisps ( MyFolder MyLispFiles / MyLisps f)
  (defun LM:GetSyntax ( file / _GetSyntax line syntax ) ;;modify to make dotted pair list, (path\\filename . LISP)
    (defun _GetSyntax ( p s / x )
      (if (setq x (vl-string-search p s))
        (cons (substr (setq s (substr s (+ x 1 (strlen p)))) 1
            (setq x (car (vl-sort (vl-remove 'nil (mapcar (function
                      (lambda ( d ) (vl-string-position d s)))
;;            '(32 9 40 41) ) ) '< ) ) ; end setq
            '(9 47 41) ) ) '< ) ) ; end setq ; numbers are character codes
        ) ) ; end cons, Substr
        (if x (_GetSyntax p (substr s (1+ x))))
        )
      ) ; end if
    ) ; end defun

   (if (setq file (open file "r"))
    (apply 'append
     (progn
       (while (setq line (read-line file))
          (if (or (= (substr line 1 1) ";") (= line nil) ) ; remove commented out lines & blank lines
            ()
            (progn ;;remove ignored items
;;              (if (wcmatch (Strcase line) "(DEFUN C:*") ;if line contains (defun c:
              (if (wcmatch (Strcase line) "(DEFUN *") ;if line starts with (Defun
                (progn
                  (setq splittext (LM:str->lst line ";")) ; ignore anything after ';'
                  (setq line (nth 0 splittext))
                  (setq splittext (LM:str->lst line (chr 34))) ; ignore strings '"'
                  (setq line "")
                  (setq count 0)
                  (while ( < count (length splittext))
                    (setq line (strcat line (nth count splittext)))
                    (setq count (+ count 2))
                  ) ; end while
;;                  (setq syntax (cons (_GetSyntax "(DEFUN C:" (strcase line)) syntax)) ;; No 'C:'
                  (setq syntax (cons (_GetSyntax "(DEFUN " (strcase line)) syntax)) ;; Keep the 'C:'
                ) ; end progn
              ) ; end if
            )
          )
        )
        (setq file (close file)) (reverse syntax)
        )
      )
    )
  ) ; end defun LM:Getsyntax

;;  (setq MyLispFiles (vl-directory-files MyFolder "*.lsp" 1))
  (princ (strcat (rtos (length MyLispFiles) 2 0) " *.LSP Files. "))
  (setq MyLisps (list)) ; blank list

  (foreach f MyLispFiles
    (setq MyLisps (append MyLisps (list (cons f (list (LM:GetSyntax (strcat MyFolder "\\" f)))))))
  ) ; end foreach

  (princ (strcat (rtos (length MyLisps) 2 0) " LISP Routines. "))
  MyLisps ; return the list
)

 

 

Edited by Steven P
Posted

In lisp there is a function AUTOLOAD that  does just that loads a lisp based on a command typed on the command line. So you just need a single lisp that has all the autoload commands in it. That custom lisp is loaded on startup in my case its Appload and add to Startup suite. I called my lisp "Autoload.lsp"

Here is sample code. You may need to add the start defun name (c:Yourlisp) as last line in the lisp that is loaded, as the load command can be anything and not necessarily the command to run it. eg ZZZ

 

(autoload "COPY0" '("COPY0"))
(autoload "COPYCOMMAND" '("ZZZ"))
(autoload "COVER" '("COVER"))
(autoload "DIMFLIP" '("DIMFLIP"))
(autoload "DRAWXFALL" '("DRAWXFALL"))
(autoload "DRAWPIPE" '("DRAWPIPE"))
(autoload "EDITRL" '("EDITRL"))

 

 

 

 

 

  • Like 2
Posted

I've never used that BigAl, do the LISP files need to be in trusted locations or is there a setting to specify your own folders maybe a network drive or similar?

Posted

I have used just a lisp name not a path in the autoload. All our customisation was in one directory on  a server, it did though have sub directory's lisp blocks icons etc. Yes if you have Acad need to add trusted paths. 

 

(if  (> (vl-string-search  "BRICSCAD" (strcase (getvar 'product))) 0)
(princ "Bricscad not found") 
(progn
(setq oldtrust (getvar 'trustedpaths))
(if (wcmatch  oldtrust "*XXX*")
(princ)
(setvar 'trustedpaths (strcat oldtrust ";" "c:\\XXX-CAD-TOOLS"))
)
)
)
(command "workspace" "save" "" "y") ; a good idea is have a new workspace say user name

(alert "\nSupport and trusted paths added")

 

 

  • Like 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...