gr8vyguy@Blogjava

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

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项目。

转载请保留http://www.blogjava.net/xilaile/archive/2007/05/13/117039.html

posted on 2007-05-12 19:23 gr8vyguy 阅读(5414) 评论(4)  编辑  收藏 所属分类: Scripting

评论

# re: NSIS脚本制作Java程序的EXE启动器 2007-10-10 07:56 enet

欢乐猪 兄

你好

NSIS 我是新手,正在研究。

问几个傻傻的问题,请高人指点迷津。

1、NSIS 打包.net 写的web应用程序。

2、NSIS 还可以做升级包程序(效果,添加删除内不增加记录,完成数据库更新,文件更新)。

感谢先。

  回复  更多评论   

# re: NSIS脚本制作Java程序的EXE启动器 2012-11-25 08:37 王其军

还可以吧  回复  更多评论   

# re: NSIS脚本制作Java程序的EXE启动器 2013-08-29 16:24 xiaomiao

请问nsis怎么实现打包了的mysql,tomcat。jdk的自动安装  回复  更多评论   

# re: NSIS脚本制作Java程序的EXE启动器 2013-10-24 03:55 于召书

如果test.jar 需要传一个参数,该怎么写?  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2007年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

公告

  • 转载请注明出处.
  • msn: gr8vyguy at live.com
  • 常用链接

    留言簿(9)

    随笔分类(68)

    随笔档案(80)

    文章分类(1)

    My Open Source Projects

    搜索

    积分与排名

    最新评论