提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、开发工具
  • 二、Springboot实现IE浏览器跳转至谷歌浏览源码
    • 1.获取谷歌浏览器可执行文件路径
    • 2.该SpringBoot项目所需要的POM和相应的配置文件
  • 二、exe4j打包SpringBoot项目的jar包
    • 1.准备所需要的jar、图标、jre等文件
    • 2.保证jar可以运行
    • 3.exe4j打包jar
  • 三、Inno Setup 编译器打包exe4j打包的exe,并将谷歌浏览器作为运行环境打包,制作成windows环境下有安装向导的exe程序
    • 1.准备系统在谷歌浏览器需要跳转url的application.properties配置文件
    • 2.准备对应windows版本谷歌浏览器的运行环境,并将谷歌浏览器运行环境全部拷贝到exe4j打包导出的文件夹中
    • 2.Inno Setup 编译器打包

前言

最近有一个需求是springboot项目实现从IE浏览器跳转至谷歌浏览器并打包成windows环境下可执行exe文件,以达到客户的小白操作。


提示:以下是本篇文章正文内容,下面案例可供参考,欢迎各位技术大牛指正。

一、开发工具

1.IDEA开发工具
  2.exe4j Wizard
  3.Inno Setup 编译器

二、Springboot实现IE浏览器跳转至谷歌浏览源码

1.获取谷歌浏览器可执行文件路径

这里我用过三种方式:
    第一种是从windows注册机中获取谷歌浏览器的地址。

第二种是直接在C盘写死预先设置的路径,然后用innoSteup把谷歌浏览器运行环境与springboot项目一起打包,并将打包后的文件夹指向代码写死的路径,以方便代码可以读取到谷歌浏览器的可执行文件。(相当于把谷歌浏览器的运行环境也一起打包了,具体做法下面会具体介绍)。个人推荐使用第二种,因为不同型号的电脑,同一电脑不同用户其注册机会不断地变化,根本无法确定谷歌浏览器的可执行文件的路径。而且这么做不需要客户安装浏览器,也可以打开谷歌浏览器。这里需要注意的是需要根据客户电脑操作系统选择相应的谷歌浏览器版本,我这里集成了32位和64位操作系统版本的谷歌浏览器。

第三种是从外部配置文件中读取

由于第二种方式谷歌浏览器路径是由自己写死的,大家可以选择路径,所以这里贴上第一种和第三种的代码。
    第一种:从windows注册机中获取谷歌浏览器的地址,这里我已经封装好了一个工具类(工具类中的ReadPropertiesUtils工具类是是第三种方式所用的工具类,代码在下面。),仅供参考:
代码如下(示例):

package com.luckyun.routing.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Properties;/*** <p>Title:utils</p>** @description: 依据操作系统环境读取本地浏览器安装路径* @author: ywj* @create: 2020-08-29 15:09*/
public class Registery {private static final Logger logger = (Logger) LoggerFactory.getLogger(Registery.class);//windows10系统谷歌浏览器注册机默认地址private static final String GOOLE_HKEY_LOCAL_MACHINE_WIN10 = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\ChromeHTML\\Application";//windows7系统谷歌浏览器注册机默认地址private static final String GOOLE_HKEY_LOCAL_MACHINE_WIN7 = "HKEY_CURRENT_USER\\Software\\AppDataLow\\Software\\JavaSoft\\DeploymentProperties";//WindowsXP系统谷歌浏览器注册机默认地址private static final String GOOLE_HKEY_LOCAL_MACHINE_WINXP = "HKEY_CLASSES_ROOT\\ChromeHTML\\shell\\open\\command";/****@Description: 获取本机的windows环境下谷歌浏览器可执行文件路径-路径读取优先级(C盘application.properties中address地址优先于从本机注册机中的地址)*@Author: ywj*@Param: []*@Return: java.lang.String*@Date: 2020/8/30 15:51**/public static String getBrowserExePath() throws IOException {Process process = null;String path = "";String line;try {Map<String, String> readProperties = ReadPropertiesUtils.getProperties();if (readProperties != null && !StringUtils.isEmpty(readProperties.get("address"))){path = readProperties.get("address");}else {//获取当前的系统属性集Properties pop = System.getProperties();String systemOsName = pop.getProperty("os.name");if (!StringUtils.isEmpty(systemOsName) && systemOsName.equals("Windows 7")){process = Runtime.getRuntime().exec("reg query ".concat(GOOLE_HKEY_LOCAL_MACHINE_WIN7));}else if (!StringUtils.isEmpty(systemOsName) && systemOsName.equals("Windows 10")){process = Runtime.getRuntime().exec("reg query ".concat(GOOLE_HKEY_LOCAL_MACHINE_WIN10));}else if (!StringUtils.isEmpty(systemOsName) && systemOsName.equals("Windows XP")){process = Runtime.getRuntime().exec("reg query ".concat(GOOLE_HKEY_LOCAL_MACHINE_WINXP));}if (process != null){InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());BufferedReader bufferedReader = new BufferedReader(inputStreamReader);while ((line = bufferedReader.readLine()) != null) {if (line.contains("chrome.exe")){path = line.toString();path = path.substring(path.indexOf(":")-1,path.lastIndexOf(".exe")+4);break;}}if (inputStreamReader != null){inputStreamReader.close();}}}}catch (Exception e){logger.error("注册机获取谷歌浏览器路径异常!",e.getMessage());}finally {if (process !=null){if (process.getInputStream() != null){process.getInputStream().close();}process.getOutputStream().close();}}return path;}
}

第三种是从外部配置文件中读取,这里我已经封装好了一个工具类,仅供参考:
代码如下(示例):

package com.luckyun.routing.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;/*** <p>Title:ReadPropertiesUtils</p>** @description: 读取配置文件* @author: ywj* @create: 2020-08-30 17:24*/
public class ReadPropertiesUtils {private static final Logger logger = (Logger) LoggerFactory.getLogger(ReadPropertiesUtils.class);//文件路径private static final String filePath = "C://luckyun//application.properties";/****@Description: 获取properties文件中的内容,并返回map*@Author: ywj*@Param: []*@Return: java.util.Map<java.lang.String,java.lang.String>*@Date: 2020/8/31 9:18**/public static Map<String, String> getProperties() throws IOException {Map<String, String> map = new HashMap<String, String>();InputStream inputStream = null;Properties properties = new Properties();;try {File file = new File(filePath);if (!file.exists()){return null;}else {inputStream = new BufferedInputStream(new FileInputStream(file));properties.load(inputStream);Set<Map.Entry<Object, Object>> entrySet = properties.entrySet();for (Map.Entry<Object, Object> entry : entrySet) {map.put((String) entry.getKey(), (String) entry.getValue());}}} catch (Exception e) {logger.error("外部配置文件解析异常!",e.getMessage());}finally {if (inputStream != null){inputStream.close();}}return map;}
}

2.该SpringBoot项目所需要的POM和相应的配置文件

POM代码
代码如下(示例):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.luckyun</groupId><artifactId>routing</artifactId><version>0.0.1-SNAPSHOT</version><name>routing</name><description>routingHop project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion><!-- 排除自带的logback依赖 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!--引入thymeleaf的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!--打包成windows服务--><plugin><groupId>cn.joylau.code</groupId><artifactId>joylau-springboot-daemon-windows</artifactId><version>1.0.RELEASE</version><executions><execution><id>make-win-service</id><phase>package</phase><goals><goal>make-win-service</goal></goals></execution></executions></plugin></plugins></build></project>

log4j.properties配置文件
代码如下(示例):

log4j.rootCategory=INFO,stdout,info,error
log4j.rootLooger=warn,stdout,info,error
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%nlog4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
log4j.appender.info.Threshold=INFO
log4j.appender.info.append=true
log4j.appender.info.File=/Users/xiejc/IdeaProjects/logs/log_info_
log4j.appender.info.DatePattern=yyyy.MM-dd'.log'log4j.logger.error=error
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
log4j.appender.error.Threshold=ERROR
log4j.appender.error.append=true
log4j.appender.error.File=/Users/xiejc/IdeaProjects/logs/log_error_
log4j.appender.error.DatePattern=yyyy.MM-dd'.log'
log4j.appender.file.layout=org.apache.log4j.PatternLayout

application.properties配置文件
代码如下(示例):

#端口
server.port=80# thymeleaf配置
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

LaunchBrowserController
代码如下(示例):

package com.luckyun.routing.controller;import com.luckyun.routing.utils.ReadPropertiesUtils;
import com.luckyun.routing.utils.Registery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Properties;/*** <p>Title:LaunchBrowserController</p>** @description: 启动谷歌浏览器* @author: ywj* @create: 2020-08-30 15:55*/
@RestController
@EnableAutoConfiguration
public class LaunchBrowserController {private static final Logger logger = (Logger) LoggerFactory.getLogger(LaunchBrowserController.class);/****@Description:从IE浏览器跳转至谷歌浏览器接口*@Author: ywj*@Param:*@Return:*@Date: 2020/9/3 17:24**/@RequestMapping(value = "")public ModelAndView redirect(Model model,HttpServletRequest request){String url = "";String path ="C:\\luckyun\\chrome.exe";try {//获得url后面的参数串String queryString = request.getQueryString();Map<String, String> readProperties = ReadPropertiesUtils.getProperties();if (readProperties != null && !StringUtils.isEmpty(readProperties.get("url"))){url = readProperties.get("url");}if (StringUtils.isEmpty(url)){return new ModelAndView("help","",model);}else {url = url.concat("?").concat(queryString);//String path = Registery.getBrowserExePath();if (!StringUtils.isEmpty(url) && !StringUtils.isEmpty(path)){ProcessBuilder proc = new ProcessBuilder(path, url);proc.start();}}}catch (Exception e){logger.error("启动谷歌浏览器异常!",e.getMessage());}return null;}/****@Description: 获取操作系统信息*@Author: ywj*@Param: []*@Return: java.lang.String*@Date: 2020/9/2 9:10**/@RequestMapping(value = "/getSystemName")public String getSystemName(){String systemInfo = "";try {Properties pop = System.getProperties(); //获取当前的系统属性集systemInfo = systemInfo.concat("操作系统的名称:").concat(pop.getProperty("os.name")).concat("    ").concat("操作系统的版本:").concat(pop.getProperty("os.version")).concat("    ").concat("操作系统的架构:").concat(pop.getProperty("os.arch"));}catch (Exception e){logger.error("获取操作系统信息异常",e.getMessage());}return systemInfo;}}

二、exe4j打包SpringBoot项目的jar包

1.准备所需要的jar、图标、jre等文件

2.保证jar可以运行

3.exe4j打包jar

1.输入软件许可

    2.选择JAR in EXE mode,点击下一步

    3.输入程序名称和结果输出路径

    4.输入exe类型、名称以及相关配置

    5.点击Advanced  Options配置exe的日志以及是windows系统环境下32位的还是64位的exe程序(其余的配置我这里选择了默认)。


    6.配置JAVA的exe的jar包

    7.配置JAVA的exe的主函数
注意:这里有一个坑,你需要去jar包里去查看你的Main函数具体是什么,这里并非是springboot的启动类

选择对应的启动类,点击下一步

    8.配置JRE的最低和最高版本

    9.点击Advanced  Options配置exe的jre环境。

注意:这里有一个坑,选择jre的时候必须选择其根目录,我这边选择其他目录打包结果运行不了。

    10.选择VM,这里选择Client hotspot VM

    11.一直选择默认到最后
    12.运行结果

三、Inno Setup 编译器打包exe4j打包的exe,并将谷歌浏览器作为运行环境打包,制作成windows环境下有安装向导的exe程序

1.准备系统在谷歌浏览器需要跳转url的application.properties配置文件

2.准备对应windows版本谷歌浏览器的运行环境,并将谷歌浏览器运行环境全部拷贝到exe4j打包导出的文件夹中

2.Inno Setup 编译器打包

1.创建一个新的脚本文件
    2.点击下一步

    3.输入程序名称和版本,点击下一步

    4.选择应用程序目标基本文件夹和应用程序文件夹名称(这个路径就是在程序安装时选择将程序所需要的运行环境文件放在哪个目录下面)。

    5.选择我们用exe4j打包的Test.exe作为应用程序主执行文件。

    6.选择添加文件夹将第一步准备的所有支撑运行环境全部放入进来。
注意:这里有一个坑,这里必须将exe4j打包的相关文件以及我们准备的jre、谷歌浏览器全部放入到一个文件夹下,并且在选择的时候选择根目录,将所有文件都加入进来后打包的程序才可以运行,不然会报No JVM could be found on your system.Please define EXE4J_JAVA_HOME.和无法打开谷歌浏览器

    7.点击下一步

    7.这里可以选择添加许可文件之类的,我这里就不在添加了,点击下一步

    8.选择安装包安装的时候指定语言,这里默认中文简体

    9.这里选择程序打包完成后导出到哪个目录、程序的名称以及我们之前准备的程序图标文件,点击下一步。

    10.点击下一步

    11.点击完成
    12.如果你对程序仅仅安装上,到这一步选择”是“,然后选择否就可以得到有安装向导的exe程序。
注意:仅仅到这一步对于程序来说是不完整的,我们还需要设置其他的。下面是我们可能需要遇到的几种情况:

1.当程序卸载的时候,我们需要删除程序安装时所产生的文件以及windows环境下开始菜单里面和桌面的快捷方式菜单。
     2.当我们重新安装同一个程序的时候,正常的逻辑应该是先停掉windows环境下程序的进程,然后删除程序安装时所产生的文件以及windows环境下开始菜单里面和桌面的快捷方式菜单,最后才开始安装。
     3.当我们希望用户在电脑开机后该程序直接自动启动,这里也是可以配置的。
     4.当我们不希望用户修改我们程序的默认安装路径,我们这里也可以设置,这样用户在安装的时候安装向导就会跳过让用户选择安装目录这一个选项。

这些配置我已经在第13步以注释的形式放置好,大家可以参考。



    13.程序功能的完善配置

;禁止用户选择安装目录,安装向导会自动跳过让用户选择将程序安装到哪个目录
DisableDirPage=yes
;生成我们之前在springboot项目中需要跳转url的配置文件,这里的G:\WinXP\application.properties路径是我们前期所准备并放到打包目录里的文件
Source: "G:\WinXP\application.properties"; DestDir:"{app}"; Flags: ignoreversion
;写入windows注册机并实现程序开机自启
[Registry]
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "testrun"; ValueData: "{app}\{#MyAppExeName}"

以下是程序卸载以及重新安装时所需要的配置

; 自定义不同语言文本
[CustomMessages]
;english.checkSoftTip=Setup detects that the software to be installed is running!%n%nClick "ok" to continue the operation after terminating the software, otherwise click "cancel" .
chinesesimp.checkSoftTip=安装程序检测到将安装的软件正在运行!%n%n点击"确定"终止软件后继续操作,否则点击"取消"。[Code]
// 自定义函数,判断软件是否运行,参数为需要判断的软件的exe名称
function KDetectSoft(strExeName: String): Boolean;
// 变量定义
var ErrorCode: Integer;
var bRes: Boolean;
var strFileContent: AnsiString;
var strTmpPath: String;  // 临时目录
var strTmpFile: String;  // 临时文件,保存查找软件数据结果
var strCmdFind: String;  // 查找软件命令
var strCmdKill: String;  // 终止软件命令
beginstrTmpPath := GetTempDir();strTmpFile := Format('%sfindSoftRes.txt', [strTmpPath]);strCmdFind := Format('/c tasklist /nh|find /c /i "%s" > "%s"', [strExeName, strTmpFile]);strCmdKill := Format('/c taskkill /f /t /im %s', [strExeName]);//ShellExec('open', ExpandConstant('{cmd}'), '/c taskkill /f /t /im 你的软件名.exe', '', SW_HIDE, ewNoWait, ErrorCode);//bRes := ShellExec('open', ExpandConstant('{cmd}'), '/c tasklist /nh|find /c /i "你的软件名.exe" > 0.txt', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);bRes := ShellExec('open', ExpandConstant('{cmd}'), strCmdFind, '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);if bRes then beginbRes := LoadStringFromFile(strTmpFile, strFileContent);strFileContent := Trim(strFileContent);if bRes then beginif StrToInt(strFileContent) > 0 then beginif MsgBox(ExpandConstant('{cm:checkSoftTip}'), mbConfirmation, MB_OKCANCEL) = IDOK then begin// 终止程序ShellExec('open', ExpandConstant('{cmd}'), strCmdKill, '', SW_HIDE, ewNoWait, ErrorCode);Result:= true;// 继续安装end else beginResult:= false;// 安装程序退出Exit;end;end else begin//MsgBox('软件没在运行', mbInformation, MB_OK);Result:= true;Exit;end;end;end;Result :=true;
end;// 开始页下一步时判断软件是否运行
function NextButtonClick(CurPageID: Integer): Boolean;
beginif 1=CurPageID then beginResult := KDetectSoft('{#MyAppExeName}');Exit;end; Result:= true;
end;// 卸载时关闭软件
function InitializeUninstall(): Boolean;
beginResult := KDetectSoft('{#MyAppExeName}');
end;//卸载已经安装的目录
function InitializeSetup(): boolean;
var  ResultStr: String;  ResultCode: Integer;
begin  if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{577CAA0D-52AF-4B54-8492-E41016DB430A}_is1', 'UninstallString', ResultStr) then  begin  ResultStr := RemoveQuotes(ResultStr);  Exec(ResultStr, '/silent', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);  end;  result := true;
end;

注意:这里有个坑,if RegQueryStringValue(HKLM, ‘SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{577CAA0D-52AF-4B54-8492-E41016DB430A}_is1’, ‘UninstallString’, ResultStr) 这个语句中的“577CAA0D-52AF-4B54-8492-E41016DB430A”是程序的id,你需要修改成你自己的id。id的查看查看方式如下:

14.以下是我的一个完整配置,仅供参考

; 脚本由 Inno Setup 脚本向导 生成!
; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档!#define MyAppName "Test"
#define MyAppVersion "1.0"
#define MyAppPublisher "我的公司"
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "Test.exe"[Setup]
; 注: AppId的值为单独标识该应用程序。
; 不要为其他安装程序使用相同的AppId值。
; (生成新的GUID,点击 工具|在IDE中生成GUID。)
AppId={{A0D56786-694D-43F7-8CBD-98A8E5B0659F}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName=C:\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=G:\Test
OutputBaseFilename=TestSetup
SetupIconFile=G:\Test\favicon.ico
Compression=lzma
SolidCompression=yes
;禁止用户选择安装目录,安装向导会自动跳过让用户选择将程序安装到哪个目录
DisableDirPage=yes [Languages]
Name: "chinesesimp"; MessagesFile: "compiler:Default.isl"[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1[Files]
Source: "G:\Test\Test.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "G:\Test\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;生成我们之前在springboot项目中需要跳转url的配置文件,这里的G:\WinXP\application.properties路径是我们前期所准备并放到打包目录里的文件
Source: "G:\WinXP\application.properties"; DestDir:"{app}"; Flags: ignoreversion
; 注意: 不要在任何共享系统文件上使用“Flags: ignoreversion”[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent;写入windows注册机并实现程序开机自启
[Registry]
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "testrun"; ValueData: "{app}\{#MyAppExeName}"; 自定义不同语言文本
[CustomMessages]
;english.checkSoftTip=Setup detects that the software to be installed is running!%n%nClick "ok" to continue the operation after terminating the software, otherwise click "cancel" .
chinesesimp.checkSoftTip=安装程序检测到将安装的软件正在运行!%n%n点击"确定"终止软件后继续操作,否则点击"取消"。[Code]
// 自定义函数,判断软件是否运行,参数为需要判断的软件的exe名称
function KDetectSoft(strExeName: String): Boolean;
// 变量定义
var ErrorCode: Integer;
var bRes: Boolean;
var strFileContent: AnsiString;
var strTmpPath: String;  // 临时目录
var strTmpFile: String;  // 临时文件,保存查找软件数据结果
var strCmdFind: String;  // 查找软件命令
var strCmdKill: String;  // 终止软件命令
beginstrTmpPath := GetTempDir();strTmpFile := Format('%sfindSoftRes.txt', [strTmpPath]);strCmdFind := Format('/c tasklist /nh|find /c /i "%s" > "%s"', [strExeName, strTmpFile]);strCmdKill := Format('/c taskkill /f /t /im %s', [strExeName]);//ShellExec('open', ExpandConstant('{cmd}'), '/c taskkill /f /t /im 你的软件名.exe', '', SW_HIDE, ewNoWait, ErrorCode);//bRes := ShellExec('open', ExpandConstant('{cmd}'), '/c tasklist /nh|find /c /i "你的软件名.exe" > 0.txt', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);bRes := ShellExec('open', ExpandConstant('{cmd}'), strCmdFind, '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);if bRes then beginbRes := LoadStringFromFile(strTmpFile, strFileContent);strFileContent := Trim(strFileContent);if bRes then beginif StrToInt(strFileContent) > 0 then beginif MsgBox(ExpandConstant('{cm:checkSoftTip}'), mbConfirmation, MB_OKCANCEL) = IDOK then begin// 终止程序ShellExec('open', ExpandConstant('{cmd}'), strCmdKill, '', SW_HIDE, ewNoWait, ErrorCode);Result:= true;// 继续安装end else beginResult:= false;// 安装程序退出Exit;end;end else begin//MsgBox('软件没在运行', mbInformation, MB_OK);Result:= true;Exit;end;end;end;Result :=true;
end;// 开始页下一步时判断软件是否运行
function NextButtonClick(CurPageID: Integer): Boolean;
beginif 1=CurPageID then beginResult := KDetectSoft('{#MyAppExeName}');Exit;end; Result:= true;
end;// 卸载时关闭软件
function InitializeUninstall(): Boolean;
beginResult := KDetectSoft('{#MyAppExeName}');
end;//卸载已经安装的目录
function InitializeSetup(): boolean;
var  ResultStr: String;  ResultCode: Integer;
begin  if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{577CAA0D-52AF-4B54-8492-E41016DB430A}_is1', 'UninstallString', ResultStr) then  begin  ResultStr := RemoveQuotes(ResultStr);  Exec(ResultStr, '/silent', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);  end;  result := true;
end;

这里附上我用的exe4j所用的版本和inno Steup所用的版本
exe4j:链接:https://pan.baidu.com/s/1MInQiCh9COoEEzYbVy7lfw
提取码:s0e4

inno Steup:链接:https://pan.baidu.com/s/1jnPXUbamSJAO4MqjJbDjSA
提取码:vfc6

谷歌浏览器windows的64位版本和32位版本的运行环境
谷歌浏览器:链接:https://pan.baidu.com/s/1KL–oswVwxs4Q7Cv0j2zgw
提取码:fkt5

SpringBoot项目从IE浏览器跳转至谷歌浏览器并打包成windows环境下可行EXE文件相关推荐

  1. springboot项目打jar包跳过单元测试test

    springboot项目打jar包跳过单元测试test 直接使用maven命令 mvn -B clean package -Dmaven.test.skip=true

  2. 解决Springboot项目在idea中能正常使用,但打包后无法运行的情况

    解决Springboot项目在idea中能正常使用,但打包后无法运行的情况 自己做一些活的时候偶然发现的bug:在springboot的web项目中,打包之前能正常的运行,包括测试类里面的代码也都是正 ...

  3. 超详细Windows环境下使用Apache部署Django项目教程

    目录 超详细Windows环境下使用Apache部署Django项目教程 1.什么是Apache 2.安装并配置Apache 2.1 下载Apache 2.2 解压Apache到文件夹 2.3 配置c ...

  4. Windows 环境下 Chrome浏览器崩溃“STATUS_INVALID_IMAGE_HASH”

    问题 Windows环境下,新版的Chrome浏览器下载安装后,打开就报错,提示错误代码为"STATUS_INVALID_IMAGE_HASH".重新打开.打开新标签页.刷新均无效 ...

  5. Windows环境下运行Jenkins项目,输出乱码

    Windows环境下运行Jenkins项目,输出乱码 问题描述 ​ python自动化测试项目部署到jenkins上执行时报错UnicodeEncodeError: 'gbk' codec can't ...

  6. 新建一个springboot项目添加@restcontroller浏览器访问一直报404

    1.用idea新建一个新的springboot项目,配置好一个controller 2.浏览器访问一直报404 3.解决方法:因为启动一个springboot应用的时候,没有指定扫描的包.所以默认扫描 ...

  7. 启动Springboot项目自动打开浏览器

    在Springboot项目的启动类里面添加 package com.itheima;import org.springframework.boot.SpringApplication; import ...

  8. SpringBoot项目打包成jar后读取包内文件报错问题解决方法

    文章目录 问题描述 解决办法 问题描述 Springboot项目在开发环境中,使用 ResourceUtils.getFile("classpath:files/test.xlsx" ...

  9. SpringBoot 项目引入本地jar包,并设置maven打包一并打入

    resources目录下新建lib文件夹,然后将需要的本地jar包放入进去 pom文件中引入本地jar包依赖 <dependency><groupId>com.XXX</ ...

  10. SpringBoot项目开发(十):引用本地jar包与打包本地jar

    标题可能有点绕口,在实际开发中,有时所引用的jar架包无法在 maven 中央仓库里找到,那么j就要引用本地jar包,然而在项目开发完成后,需要打包部署时,引用的本地jar包没有打包进去部署包,就会导 ...

最新文章

  1. 【资源共享】RK3288 WiFiBT 开发配置参考说明
  2. 【正一专栏】恒大中超七连冠到手了
  3. 九十七、轻松搞定Python中的PDF办公自动化系列
  4. 致所有.Net者和有梦想的朋友们 - 共勉
  5. 设计计算机程序时 要考虑计算的过程,算法和程序设计练习题复习课程(6页)-原创力文档...
  6. 阿里达摩院提出新型优化方法,一行代码即可替换现有优化器
  7. 2021-09-07LRUCache机制
  8. Win10 安装 IE11 教程
  9. flash swf文件 网页播放功能方案实现
  10. linux优麒麟iso镜像,国产优麒麟操作系统官方下载
  11. python经济统计学论文_Python商务与经济统计学-1
  12. linux 内核PCI驱动总结记录
  13. nltk英文词性分析
  14. BIM+GIS开启公路工程全生命周期管理新模式
  15. 预编译器错误:代码使用了less语言,但未安装相应的编译器插件,请前往插件市场安装该插件
  16. Java设计模式之——适配器
  17. 【Labview】基于Labview的BMI计算器
  18. HART475艾默生手操器维修注意事项及指标特点
  19. 网络安全之入侵检测系统
  20. axios 之 post请求参数格式不正确得问题

热门文章

  1. 【SUSE Linux kernel版本升级】SUSE Linux Enterprise Server 12 SP5
  2. java乱码处理_Java处理乱码问题
  3. 开发与测试的相爱相杀
  4. Javascript+PHP实现在线拍照功能
  5. 超级好用的网站整站下载工具
  6. 【游戏 #1】GTA5OL快速上线方法
  7. python计算化学浓度_理论与计算化学 - 计算模拟 - 程序代码 - 小木虫论坛-学术科研互动平台...
  8. 怎么把mpg转成mp4,mpg转mp4方法
  9. Tomcat:JAVA_HOME should point to a JDK not a JRE解决
  10. SpringBoot实现本地、网络文件下载、zip压缩包批量下载