NSIS脚本制作Java程序的EXE启动器,nsisjavaexe启动器
NSIS脚本制作Java程序的EXE启动器,nsisjavaexe启动器
nsis调用外部程序的的命令是exec,比如exec "notepad", 将启动windows的默认文本编辑器notepad。同样的道理可以用"java -jar test.jar"启动test.jar。
name "java launcher"
caption "java launcher"
icon "java launcher.ico"
outfile "java launcher.exe"
silentinstall silent
autoclosewindow true
showinstdetails nevershow
section ""
exec "java -jar test.jar"
sectionend
将上面这段nsis脚本拷贝到一个nsi文件中,用nsis编译器编译,将产生java launcher.exe。双击java launcher.exe将启动同一目录下的test.jar文件,test.jar必须能够用java-jar test.jar启动,也就是说test.jar的manifest的library和main-class都要正确设值好。否则的话,你可以用java -classpath jar1;jar2 main_class来启动。
如何编译nsis脚本请参看我之前的一篇随笔 安装程序制作系统nsis(nullsoft scriptable install system)。
上面这个启动器的一个问题是会打开一个控制台窗口,这是因为用了java命令,只要改为javaw就不会出现控制台了。 另外一个问题是不够健壮,只有当java或者javaw命令在当前目录下或者在path上,才能正确启动。也许你想带着一个jre发布你的程序,那么就不能够去启动系统的java命令。下面来加入寻找java命令目录的功能,寻找的顺序为
当前目录下的jre子目录, 如果你的发布程序里带了一个jre,优先启动。
环境变量java_home 指定的目录
在注册表中,hklm\software\javasoft\java runtime environment下保存着安装的jre的目录信息。
当前目录和系统环境变量path中的目录
脚本
name "java launcher"
caption "java launcher"
icon "java launcher.ico"
outfile "java launcher.exe"
silentinstall silent
autoclosewindow true
showinstdetails nevershow
section ""
call getjre
pop $r0
; change for your purpose (-jar etc.)
strcpy $0 '"$r0" -jar test.jar'
setoutpath $exedir
execwait $0
sectionend
function getjre
push $r0
push $r1
clearerrors
strcpy $r0 "$exedir\jre\bin\javaw.exe"
iffileexists $r0 jrefound
strcpy $r0 ""
clearerrors
readenvstr $r0 "java_home"
strcpy $r0 "$r0\bin\javaw.exe"
iferrors 0 jrefound
clearerrors
readregstr $r1 hklm "software\javasoft\java runtime environment" "currentversion"
readregstr $r0 hklm "software\javasoft\java runtime environment\$r1" "javahome"
strcpy $r0 "$r0\bin\javaw.exe"
iferrors 0 jrefound
strcpy $r0 "javaw.exe"
jrefound:
pop $r1
exch $r0
functionend
function getjre定义了寻找jre的函数,找到的javaw命令的路径可以从r0中取回。r0,r1是nsis预定义的寄存器,或者说是变量,push $r0将r0的内容压进堆栈,pop $r0从堆栈中取回r0的内容。这一点和汇编程序很像。getjre按定义好的顺序判断指定路径下的是否存在javaw,如果是,返回。比如
readenvstr $r0 "java_home"读入java_home的值到r0
strcpy $r0 "$r0\bin\javaw.exe"加上\bin\javaw.exe
iffileexists $r0 jrefound如果r0指定的文件存在,跳转到jrefound
readregstr读取注册表中的键值。exch $r0交换r0和堆栈头元素的值。其他函数从字面上就可以理解了,不需要过多的解释。
最后要说明的是,这里用execwait启动java命令,而不是exec。区别是exec马上退出java launcher.exe的进程,而execwait不退出,也就是说用execwait在关闭程序之前,有两个活动进程,java launcher.exe和javaw.exe。这正是eclipse3.3之前的exe启动器的情况,比如eclipse3.2启动后,任务管理器里有eclipse.exe和javaw.exe两个进程。使用execwait的原因是exec在windows 2000下出现的一个问题,在使用程序的过程中,如果用户改变了桌面属性,比如背景图,系统就挂掉了。eclipse在3.3之后改成了使用java的invocation interface启动startup.jar。详细的情况请看org.eclipse.equinox.executable项目。
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
相关文章
- 暂无相关文章
用户点评