zoukankan      html  css  js  c++  java
  • 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项目。
  • 相关阅读:
    React——JSX语法【三】
    React——虚拟DOM创建的两种方式【二】
    Nginx——虚拟主机简介
    Linux——Centos8虚拟机添加网卡未显示
    React——React简介和基本使用【一】
    Linux——删除系统python导致yum无法使用
    SonarQube——Docker搭建SonarQube服务
    Linux——配置SSH免密登录
    Jumpserver——如何替换多因子认证
    GitLab——如何快速部署GitLab仓库
  • 原文地址:https://www.cnblogs.com/zdxster/p/2015552.html
Copyright © 2011-2022 走看看