NSIS脚本制作Java程序的EXE启动器

[转] http://www.blogjava.net/xilaile/archive/2007/05/13/117039.html

 

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命令目录的功能,寻找的顺序为

  1. 当前目录下的jre子目录, 如果你的发布程序里带了一个jre,优先启动。
  2. 环境变量JAVA_HOME 指定的目录
  3. 在注册表中,HKLM/SOFTWARE/JavaSoft/Java Runtime Environment下保存着安装的JRE的目录信息。
  4. 当前目录和系统环境变量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项目。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值