[原创]AutoCAD二次开发程序的安装制作向导(测试),支持2006
以前我发表过一个LISP Setup用于简单的LISP程序的安装。这个程序需要设置AutoCAD菜单文件。而一些坛友对于必须要用菜单文件也很不爽。毕竟这样就不够简单了。而从AutoCAD 2006开始,菜单文件发生了变化,尤其是它的注册表结构变了。这个程序基本上废了。<BR><BR>近日我重新弄了一个。目标是更加简单。现在支持AutoCAD 2006,但不再支持AutoCAD R14了。希望它可以自动支持后续的AutoCAD版本。给大家测试一下先:尝鲜下载:<A href="http://quelea.w3.zccn.net/blogview.asp?logID=42" target="_blank" >http://quelea.w3.zccn.net/blogview.asp?logID=42</A>
后面我有空会提供更加详细一点的信息。欢迎讨论。<BR> 好东西,但是我不知道,如何增加支持 文件搜索路径. 下载后看看 spshchen发表于2005-4-10 9:39:00static/image/common/back.gif好东西,但是我不知道,如何增加支持 文件搜索路径.
这个我会稍后写个教程解释一下。 我先贴一段例程,这段你可以参考修改后加到启动时自动加载的文件中去。;; 取得本安装程序的路径
;; AppID即为本次安装所使用的ID
(defun GetApplicationPath (AppID)
(vl-registry-read
(strcat
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
AppID
"_is1"
)
"Inno Setup: App Path"
)
);;;AddSupportPath
;;;添加文件夹到AutoCAD支持搜索路径中的指定位置
;;;参数
;;;文件夹路径及插入的位置(0时插入前端)
;;;示例
;;;(addSupportPath "c:\\myFolder" 2)
;;;注意
;;;位置参数为空时将文件夹添加到路径最后。位置参数为0时将文件夹添加到路径最前端。
(defun addSupportPath (dir pos / tmp c)
(setqtmp ""
c -1
)
(if (not pos)
(setq tmp (strcat (getenv "ACAD") ";" dir))
(mapcar '(lambda (x)
(setq tmp (if (= (setq c (1+ c)) pos)
(strcat tmp ";" dir ";" x)
(strcat tmp ";" x)
)
)
)
(parse (getenv "ACAD") ";")
)
)
(setenv "ACAD" tmp)
(princ)
);;;removeSupportPath
;;;从AutoCAD支持搜索路径中移去指定文件夹
;;;参数
;;;所要移去的文件夹
;;;示例
;;;(removeSupportPath "c:\myFolder")
(defun removeSupportPath (dir / tmp)
(setq tmp "")
(mapcar '(lambda (x)
(if (/= (strcase x) (strcase dir))
(setq tmp (strcat tmp x ";"))
)
)
(parse (getenv "ACAD"))
)
(setenv "ACAD" (substr tmp 1 (1- (strlen tmp))))
(princ)
);; 加载菜单样例:
(defun AddDemoMenu ()
(if (menugroup "DemoMenu"); 菜单组名为DemoMenu, 已经加载
(progn
(command "_menuunload" "DemoMenu")
(command "_menuload" "DemoMenu.mnu")
(menucmd "p8=+DemoMenu.pop1")
(menucmd "p9=+DemoMenu.pop2")
(menucmd "p10=+DemoMenu.pop3")
(princ "\n DemoMenu 菜单载入.")
)
(progn
(command "_menuload" "DemoMenu.mnu")
(menucmd "p8=+DemoMenu.pop1"); 插在第8个位子
(menucmd "p9=+DemoMenu.pop2"); 插在第8个位子
(menucmd "p10=+DemoMenu.pop3"); 插在第10个位子
(princ "\n DemoMenu 菜单载入.")
)
)
) 太好了,我刚需要这个东西,这样我就可以做个自己的工具集了, 我安装了程序后,命令程序是可以用,但在CAD2005里看不到我的菜单,帮帮忙。
我的原文件:
1、wltool2005.mnu
***MENUGROUP=WLTOOL<BR>***POP1
[实用工具(&A)]<BR>ID_TCCC [图层(&)]^C^Cjccc<BR>ID_CLHWTA [地质岩性(&H)]^C^C$i=WLTOOL.KUAWEN $i=*<BR>ID_iFM [测绘图库(&I)]^C^C$i=WLTOOL.DOOR $i=*<BR>ID_TT ^C^CTT<BR>ID_gch [高程点输入(&t)]^C^CTT0<BR>ID_linetopl [转换LINE线至LWPOLYLINE(&t)]^C^Clinetopl<BR>ID_lwtopl [转换LWPOLYLINE线至POLYLINE(&t)]^C^Clwtopl<BR>ID_linetype [定制线型(&L)]^C^C-linetype<BR>ID_tl [地质图例(&D)]^C^C$i=WLTOOL.dzht $i=*
[--]<BR>ID_MnEXDraw [总图线型]^C^C$i=WLTOOL.FSLTCHG $i=*<BR> [绿化线型]^C^C$i=WLTOOL.TREELT $i=*
2、wltool.lsp
;;; 判断是否加载本文件<BR>(if (car (atoms-family 1 '("vl-load-com")))<BR> (vl-load-com)<BR> ;;else<BR> (progn<BR> (Alert<BR> "这个程序集是为AutoCAD 2000以及更高的版本设计的,许多程序有可能在没有Visual Lisp for R14支持的AutoCAD R14上不能正确地运行。"<BR> )<BR> (exit) ; 版本不符,退出加载。<BR> )<BR>)<BR>;;; 以下定义文件中用到的函数<BR>;;;----------------------------------------------------------------------------------
;;; 取得本程序的路径<BR>;;; ---------------------------------------------------------------------------------<BR>(defun GetMyApplicationPath (AppID)<BR> (vl-registry-read<BR> (strcat<BR> "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"<BR> AppID<BR> "_is1"<BR> )<BR> "Inno Setup: App Path"<BR> )<BR>)
(defun GetWLTOOLPath ()<BR> (GetMyApplicationPath "WLTOOL for AutoCAD")<BR>)
;;; 解析字符串为表(函数来自明经通道转载)<BR>;;; ---------------------------------------------------------------------------------<BR>(defun strParse (Str Delimiter / SearchStr StringLen return n char)<BR> (setq SearchStr Str)<BR> (setq StringLen (strlen SearchStr))<BR> (setq return '())<BR> (while (&gt StringLen 0)<BR> (setq n 1)<BR> (setq char (substr SearchStr 1 1))<BR> (while (and (/= char Delimiter) (/= char ""))<BR> (setq n (1+ n))<BR> (setq char (substr SearchStr n 1))<BR> ) ;_ end of while<BR> (setq return (cons (substr SearchStr 1 (1- n)) return))<BR> (setq SearchStr (substr SearchStr (1+ n) StringLen))<BR> (setq StringLen (strlen SearchStr))<BR> ) ;_ end of while<BR> (reverse return)<BR>) ;_ end of defun
;;; 反解析表为字符串(函数来自明经通道转载)<BR>;;; ---------------------------------------------------------------------------------<BR>(defun StrUnParse (Lst Delimiter / return)<BR> (setq return "")<BR> (foreach str Lst<BR> (setq return (strcat return Delimiter str))<BR> ) ;_ end of foreach<BR> (substr return 2)<BR>) ;_ end of defun
;;; 移除支持文件搜索路径<BR>;;; ---------------------------------------------------------------------------------<BR>(defun QF_RemoveSupportPath (PathToRemove / supportlist)<BR> (setq supportlist (strparse (getenv "ACAD") ";"))<BR> (setq supportlist (vl-remove "" supportlist))<BR> (setq supportlist<BR> (vl-remove-if<BR> '(lambda (x) (= (strcase x) (strcase PathToRemove)))<BR> supportlist<BR> )<BR> )<BR> (setenv "ACAD" (strUnParse supportlist ";"))<BR>)
;;; 添加支持文件搜索路径<BR>;;; ---------------------------------------------------------------------------------<BR>;;; note: 第二个参数如果为真, 插最前,否则插最后<BR>;;; <BR>(defun QF_AddSupportPath (PathToAdd isFirst / supportlist)<BR> (QF_RemoveSupportPath PathToAdd)<BR> (setq supportlist (strparse (getenv "ACAD") ";"))<BR> (setq supportlist (vl-remove "" supportlist))<BR> (if isFirst<BR> (setq supportlist (cons PathToAdd supportlist))<BR> (setq supportlist (append supportlist (list PathToAdd)))<BR> )<BR> (setenv "ACAD" (strUnParse supportlist ";"))<BR>)
;;; 根据不同的AutoCAD版本加载不同的菜单文件:<BR>(defun Load_WLTOOLMenu (/ acadver)<BR> (setq acadver (atof (getvar "acadver")))<BR> (cond<BR> ((and<BR> (&gt = acadver 15.0)<BR> (&lt acadver 16.0)<BR> )<BR> (command "_menuload" "WLTOOL.mnu")<BR> )<BR> ((and<BR> (&gt = acadver 16.0)<BR> (&lt= acadver 16.1)<BR> )<BR> (command "_menuload" "WLTOOL2005.mnu")<BR>;| ((&gt;= acadver 16.2) (command "_menuload" "QTools2006.mnu"))<BR> )<BR>)<BR>|;<BR>;;; The following code "placemenu" written by LUCAS<BR>;;; 插入菜单条 Placemenu由LUCAS编写<BR>;;; ---------------------------------------------------------------------------------<BR> (defun WLTOOL_PlaceMenu (/ n)<BR> (if (menugroup "WLTOOL")<BR> (progn<BR> (setq n 1)<BR> (while<BR> (&lt n 24)<BR> (if (menucmd (strcat "P" (itoa n) ".1=?"))<BR> (setq n (+ n 1))<BR> (progn<BR> (if (&gt n 3)<BR> (setq n (- n 2))<BR> (setq n 3)
) ;if<BR> (menucmd (strcat "p" (itoa n) "=+WLTOOL.pop3")<BR> )<BR> (menucmd (strcat "p" (itoa n) "=+WLTOOL.pop2")<BR> )<BR> (menucmd (strcat "p" (itoa n) "=+WLTOOL.pop1")<BR> )<BR> (setq n 25)<BR> ) ;progn<BR> ) ;if<BR> )<BR> ) ;while<BR> ) ;progn<BR> ) ;if<BR> (princ)<BR> )
;;; 初始化主函数<BR>;;; ---------------------------------------------------<BR> (defun<BR> Init_WLTOOL<BR> ()<BR> ;; 添加支持路径<BR> (QF_AddSupportPath (GetWLTOOLPath) nil)<BR> (QF_AddSupportPath<BR> (strcat (GetWLTOOLPath) "<A href="file://DOOR/" target="_blank" >\\DOOR</A>")<BR> nil<BR> )<BR> (QF_AddSupportPath<BR> (strcat (GetWLTOOLPath) "<A href="file://FONTS/" target="_blank" >\\FONTS</A>")<BR> nil<BR> )<BR> (QF_AddSupportPath<BR> (strcat (GetWLTOOLPath) "<A href="file://LINE/" target="_blank" >\\LINE</A>")<BR> nil<BR> )<BR> (QF_AddSupportPath<BR> (strcat (GetWLTOOLPath) "<A href="file://LISP/" target="_blank" >\\LISP</A>")<BR> nil<BR> )<BR> (QF_AddSupportPath<BR> (strcat (GetWLTOOLPath) "<A href="file://PAT/" target="_blank" >\\PAT</A>")<BR> nil<BR> )<BR> (QF_AddSupportPath<BR> (strcat (GetWLTOOLPath) "<A href="file://SLB/" target="_blank" >\\SLB</A>")<BR> nil<BR> )
;; 如果菜单组还没有被加载,则加载之<BR> (if (not (menugroup "WLTOOL"))<BR> (Load_WLTOOLMenu)<BR> )
;; 安排菜单条的位置<BR> (WLTOOL_PlaceMenu)
(princ)<BR> )<BR> )<BR>;;; 以上函数部分定义完毕
;;; -----------------------------------------------------<BR>;;; 主程序:<BR>;;; -----------------------------------------------------<BR> (princ "\n加载WLTOOL工具集……")
(setq WLTOOL_cmdecho_save (getvar "cmdecho"))<BR> (setvar "cmdecho" 0)
;;; 执行初始化<BR> (Init_WLTOOL)
(setvar "cmdecho" WLTOOL_cmdecho_save)<BR> (setq WLTOOL_cmdecho_save nil)
(princ "\nWLTOOL工具集加载完毕。版本 2005.4")<BR> (princ)
;; autoload<BR> (autoload "wltool" '("JC" "JCCC" "WL" "LWTOPL2"))<BR> ;; ……下略<BR>) 请问一个问题:<BR>在ISetup制作安装向导的时候,如何在开始安装之前判别系统有没有装AUTOCAD,就象秋枫以前的那个安装向导一样,我知道是读注册表,但具体的实现还是不会,能指点指点吗?<BR> 多谢!不过需要好好研究了! 本帖最后由 作者 于 2005-4-23 9:58:25 编辑 <br /><br /> wengsg发表于2005-4-22 17:22:00static/image/common/back.gif(menucmd (strcat \"p\" (itoa n) \"=+WLTOOL.pop3\") ) (menucmd (strcat \"p\" (itoa n) \"=+WLTOOL.pop2\") ) (menucmd (strcat \"p\" (itoa n) \"=+WLTOOL.pop1\") ) ...
这里你只有一条菜单,因此,
(menucmd (strcat "p" (itoa n) "=+WLTOOL.pop3")<BR> )<BR> (menucmd (strcat "p" (itoa n) "=+WLTOOL.pop2")<BR> )
这两句是多余的,而且我认为会导致LSP出错,从这里中断执行。因此后面的代码没有执行。
你可以在Vlisp调试器中逐句单步执行测试。<BR><BR>
另, 你的贴文中的&gt符号之类的不知你原文是否存在……这个也是不对头的。 我前面贴的源代码中有这些东东是因为明经通道的论坛的原因,自动转化了一些符号。我现在已经改过来了。请重新拷贝。
这个样例LISP程序只是我提供的一个解决方案。你完全可以不必照搬。如果其中有什么错误或不妥我相信各高手也会有自己的看法。因为它是纯lisp程序,我相信大家自己搞得定的。在晓东cad空间论坛上我也贴了这个教程,有些网友对这段代码作了改进,我觉得也挺不错的。 onej发表于2005-4-22 18:33:00static/image/common/back.gif请问一个问题:在ISetup制作安装向导的时候,如何在开始安装之前判别系统有没有装AUTOCAD,就象秋枫以前的那个安装向导一样,我知道是读注册表,但具体的实现还是...
<BR>如果ISetup是指Inno Setup的话,在Code段写下:
const<BR> AutoCADKey = 'Software\Autodesk\AutoCAD';
function AutoCADInstalled: boolean;<BR>begin<BR> Result:=RegKeyExists(HKLM, AutoCADKey);<BR>end;<BR>
function InitializeSetup(): Boolean;<BR>var<BR>begin<BR> Result := AutoCADInstalled;<BR>end;