说明:该文章有配套资源省去配置解压下载安装麻烦,可以直接安装后,对配置文件修改后即可食用。
手把手教你制作Windows离线安装包:Inno Setup打包SpringBoot+Vue项目实战教程
一、前提准备
1.工具及插件及包
1.需要使用到Autolt制作启动键本并打成exe作为启动窗口 下载地址:Autolt下载
2.使用inno setUp将前后端文件以及各个插件工具打到一个包里供离线安装 下载地址:inno setUp下载
3.后端jar包
4.前端dist包
5.jre环境(解压后得文件夹)(把你本地jre文件夹复制过来就行)
6.Nginx(解压后得文件夹 带exe可执行文件)Nginx下载
7.MySql(解压后得文件夹 带exe可执行文件)Mysql安装教程
8.Redis(解压后得文件夹 带exe可执行文件)redis安装教程
9.Dbsyncer(这个是数据库同步得 离线设备有网得时候可以把中央数据库得数据同步过来,不需要可以忽略)Dbsyncer下载
2.目录结构
D:\test/
├── 📄 AppLauncher.au3
├── 📄 AppLauncher.exe
├── 📄 logo.ico
├── 📄 Setup.iss
├── 📂 backend/
│ └── 📄 app.jar
├── 📂 dbsyncer/
│ └── 📂 dbsyncer-2.0.7/
│ ├── 📂 bin/
│ ├── 📂 conf/
│ ├── 📂 data/
│ ├── 📂 lib/
│ ├── 📂 logs/
│ └── 📂 plugins/
├── 📂 frontend/
│ └── 📂 dist/
├── 📂 jre/
│ ├── 📂 bin/
│ ├── 📂 legal/
│ └── 📂 lib/
├── 📂 mysql/
│ ├── 📄 init.sql
│ ├── 📄 LICENSE
│ ├── 📄 my.ini
│ ├── 📄 README
│ ├── 📂 bin/
│ └── 📂 data/
├── 📂 nginx/
│ ├── 📄 nginx.exe
│ ├── 📂 conf/
│ ├── 📂 contrib/
│ ├── 📂 docs/
│ ├── 📂 html/
│ ├── 📂 logs/
│ └── 📂 temp/
└── 📂 redis/
3.效果图:
二、流程
1.创建目录结构(按照上方创建好最外层目录结构,也可以直接下载我这个文章搭配得资源)
2.将所需东西放置或解压到对应目录
更改配置文件
由于一些工具配置文件需绝对路径,所以这次安装包安装器是固定路径安装,用户不可修改标注路径得需统一(D:\名称)
1.后端配置文件port端口记下来
2.mysql配置文件\mysql\my.ini(skip-grant-tables 跳过密码)
[mysqld]
skip-grant-tables
basedir=路径\mysql
datadir=路径\mysql\data
port=3306
character-set-server=utf8mb4
default-storage-engine=INNODB
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES[mysql]
default-character-set=utf8mb4[client]
port=3306
default-character-set=utf8mb4#explicit_defaults_for_timestamp = 1
3.nginx配置文件\nginx\conf\nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;# 后端API服务配置(指向SpringBoot应用,端口)
upstream backend {
server 127.0.0.1:后端端口号;
keepalive 32;
}server {
# 监听80端口
listen 80;
server_name localhost;
# 前端静态文件目录 - 使用绝对路径指向您的前端文件
root "路径\frontend\dist";
index index.html index.htm;# 代理配置:将所有API请求转发到后端应用 (30008端口)
location /api/ {
proxy_pass http://127.0.0.1:后端端口号/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
# 支持WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}# 支持Vue Router的history模式 - 这是关键配置
location / {
try_files $uri $uri/ /index.html;
}# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}# 禁止访问隐藏文件
location ~ /\. {
deny all;
}# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 本地日志
a***ess_log logs/a***ess.log;
error_log logs/error.log;
}
}
4.AppLauncher.au3(启动程序)
; 应用程序启动器 - 优化版(带日志窗口和按钮状态管理)
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiEdit.au3>
#include <ScrollBarConstants.au3>; 全局变量
Global $hGUI, $hBtnStart, $hBtnStop, $hBtnExit, $hStatus, $hLogEdit
Global $sInstallPath = @ScriptDir
Global $pidMySQL = 0, $pidRedis = 0, $pidDbsyncer = 0, $pidBackend = 0, $pidNginx = 0
Global $sRootPwd = "" ; root密码(无密码则留空); 创建主窗口
Func _Main()
$hGUI = GUICreate("应用程序控制器", 600, 500)
GUISetFont(10)
$hBtnStart = GUICtrlCreateButton("启动服务", 50, 20, 100, 30)
$hBtnStop = GUICtrlCreateButton("停止服务", 250, 20, 100, 30)
$hBtnExit = GUICtrlCreateButton("退出", 450, 20, 100, 30)
; 初始状态:启动按钮可用,停止按钮不可用
GUICtrlSetState($hBtnStart, $GUI_ENABLE)
GUICtrlSetState($hBtnStop, $GUI_DISABLE)
$hStatus = GUICtrlCreateLabel("服务状态: 未运行", 50, 70, 500, 30)
GUICtrlSetFont($hStatus, 10, 800)
GUICtrlCreateLabel("服务日志:", 50, 110, 100, 20)
$hLogEdit = GUICtrlCreateEdit("", 50, 130, 500, 300, BitOR($ES_READONLY, $ES_AUTOVSCROLL, $WS_VSCROLL))
GUICtrlSetFont($hLogEdit, 9)
_Log("应用程序控制器已启动")
_Log("安装路径: " & $sInstallPath)
_Log("点击'启动服务'按钮开始运行所有服务")
GUISetState(@SW_SHOW)
Do
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE, $hBtnExit
_StopAllServices()
Exit
Case $hBtnStart
_StartAllServices()
; 启动后禁用启动按钮,启用停止按钮
GUICtrlSetState($hBtnStart, $GUI_DISABLE)
GUICtrlSetState($hBtnStop, $GUI_ENABLE)
Case $hBtnStop
_StopAllServices()
; 停止后禁用停止按钮,启用启动按钮
GUICtrlSetState($hBtnStop, $GUI_DISABLE)
GUICtrlSetState($hBtnStart, $GUI_ENABLE)
EndSwitch
Until $nMsg = $GUI_EVENT_CLOSE
EndFunc; 日志输出(带时间戳+自动滚动)
Func _Log($sMessage)
Local $sTime = "[" & @HOUR & ":" & StringFormat("%02d", @MIN) & ":" & StringFormat("%02d", @SEC) & "] "
Local $sNewLog = GUICtrlRead($hLogEdit) & $sTime & $sMessage & @CRLF
GUICtrlSetData($hLogEdit, $sNewLog)
_GUICtrlEdit_LineScroll($hLogEdit, 0, _GUICtrlEdit_GetLineCount($hLogEdit))
EndFunc; 启动所有服务(优化版)
Func _StartAllServices()
_Log("===== 开始启动所有服务 =====")
GUICtrlSetData($hStatus, "服务状态: 正在启动...")
; 1. 启动MySQL(含初始化)
If _StartMySQL() = 0 Then
_Log("MySQL启动失败,终止服务启动流程")
GUICtrlSetData($hStatus, "服务状态: MySQL启动失败")
; 启动失败时恢复按钮状态
GUICtrlSetState($hBtnStop, $GUI_DISABLE)
GUICtrlSetState($hBtnStart, $GUI_ENABLE)
Return
endif
; 2. 启动Redis
If _StartRedis() = 0 Then
_Log("Redis启动失败,继续启动其他服务")
endif
; 2. 启动数据同步服务这个不需要可以删掉
If _StartDbsyncer() = 0 Then
_Log("数据同步服务启动失败,继续启动其他服务")
endif
; 3. 启动后端服务
If _StartBackend() = 0 Then
_Log("后端服务启动失败,继续启动其他服务")
endif
; 4. 启动Nginx
If _StartNginx() = 0 Then
_Log("Nginx启动失败,继续启动其他服务")
endif
; 5. 打开浏览器
Run('explorer.exe http://localhost')
_Log("已打开浏览器访问: http://localhost")
GUICtrlSetData($hStatus, "服务状态: 运行中 - 访问地址: http://localhost")
_Log("===== 所有服务启动完成 =====")
EndFunc; 启动MySQL(独立函数)
Func _StartMySQL()
_Log("启动MySQL服务...")
$pidMySQL = Run($sInstallPath & "\mysql\bin\mysqld.exe --defaults-file=" & $sInstallPath & "\mysql\my.ini", $sInstallPath & "\mysql\bin", @SW_HIDE)
If Not ProcessExists($pidMySQL) Then
_Log("错误: MySQL进程启动失败")
Return 0
endif
; 动态等待MySQL就绪(最多60秒)
Local $iWait = 0, $bReady = False
While $iWait < 60 And Not $bReady
Local $iResult = RunWait( _
$sInstallPath & "\mysql\bin\mysql.exe -u root " & ($sRootPwd <> "" ? "-p" & $sRootPwd : "") & " -e ""SELECT 1""", _
$sInstallPath & "\mysql\bin", @SW_HIDE _
)
If $iResult = 0 Then
$bReady = True
Else
Sleep(2000)
$iWait += 2
_Log("等待MySQL启动中...已等待 " & $iWait & " 秒")
endif
WEnd
If Not $bReady Then
_Log("错误: MySQL启动超时(60秒)")
ProcessClose($pidMySQL)
$pidMySQL = 0
Return 0
endif
_Log("MySQL启动成功 (PID: " & $pidMySQL & ")")
Return 1
EndFunc; 启动Redis(独立函数)
Func _StartRedis()
_Log("启动Redis服务...")
$pidRedis = Run($sInstallPath & "\redis\redis-server.exe " & $sInstallPath & "\redis\redis.windows.conf", $sInstallPath & "\redis", @SW_HIDE)
If @error Or Not ProcessExists($pidRedis) Then
_Log("错误: Redis启动失败")
Return 0
endif
_Log("Redis启动成功 (PID: " & $pidRedis & ")")
Sleep(1000)
Return 1
EndFunc; 启动数据同步(独立函数)这个不需要可以删掉
Func _StartDbsyncer()
_Log("启动数据同步服务...")
$pidDbsyncer = Run($sInstallPath & "\dbsyncer\dbsyncer-2.0.7\bin\startup.bat ", $sInstallPath & "\dbsyncer\dbsyncer-2.0.7\bin", @SW_HIDE)
If @error Or Not ProcessExists($pidDbsyncer) Then
_Log("错误: 数据同步服务启动失败")
Return 0
endif
_Log("数据同步服务启动成功 (PID: " & $pidDbsyncer & ")")
Sleep(1000)
Return 1
EndFunc; 启动后端服务(独立函数)
Func _StartBackend()
_Log("启动后端服务(端口30008)...")
$pidBackend = Run($sInstallPath & "\jre\bin\java.exe -jar " & $sInstallPath & "\backend\app.jar", $sInstallPath & "\backend", @SW_HIDE)
If @error Or Not ProcessExists($pidBackend) Then
_Log("错误: 后端服务启动失败")
Return 0
endif
_Log("后端服务启动成功 (PID: " & $pidBackend & ")")
Sleep(20000) ; 后端启动可能较慢,延长等待
Return 1
EndFunc; 启动Nginx(独立函数)
Func _StartNginx()
_Log("启动Nginx服务...")
$pidNginx = Run($sInstallPath & "\nginx\nginx.exe", $sInstallPath & "\nginx", @SW_HIDE)
If @error Or Not ProcessExists($pidNginx) Then
_Log("错误: Nginx启动失败")
Return 0
endif
_Log("Nginx启动成功 (PID: " & $pidNginx & ")")
Sleep(1000)
Return 1
EndFunc; 停止所有服务(优化版)
Func _StopAllServices()
_Log("===== 开始停止所有服务 =====")
GUICtrlSetData($hStatus, "服务状态: 正在停止...")
; 1. 停止Nginx
If $pidNginx And ProcessExists($pidNginx) Then
_Log("停止Nginx服务...")
Run($sInstallPath & "\nginx\nginx.exe -s quit", $sInstallPath & "\nginx", @SW_HIDE)
ProcessWaitClose($pidNginx, 5)
If ProcessExists($pidNginx) Then
ProcessClose($pidNginx)
_Log("Nginx已强制终止")
Else
_Log("Nginx已正常停止")
endif
$pidNginx = 0
endif
; 2. 停止后端服务
If $pidBackend And ProcessExists($pidBackend) Then
_Log("停止后端服务...")
ProcessClose($pidBackend)
_Log("后端服务已停止")
$pidBackend = 0
endif
; 2. 停止数据同步服务这个不需要可以删掉
If $pidDbsyncer And ProcessExists($pidDbsyncer) Then
_Log("停止数据同步服务...")
ProcessClose($pidDbsyncer)
_Log("停止数据同步服务已停止")
$pidDbsyncer = 0
endif
; 3. 停止Redis
If $pidRedis And ProcessExists($pidRedis) Then
_Log("停止Redis服务...")
Run($sInstallPath & "\redis\redis-cli.exe shutdown", $sInstallPath & "\redis", @SW_HIDE)
Sleep(1000)
If ProcessExists($pidRedis) Then
ProcessClose($pidRedis)
_Log("Redis已强制终止")
Else
_Log("Redis已正常停止")
endif
$pidRedis = 0
endif
; 4. 停止MySQL
If $pidMySQL And ProcessExists($pidMySQL) Then
_Log("停止MySQL服务...")
Run($sInstallPath & "\mysql\bin\mysqladmin.exe -u root " & ($sRootPwd <> "" ? "-p" & $sRootPwd : "") & " shutdown", $sInstallPath & "\mysql\bin", @SW_HIDE)
Sleep(2000)
If ProcessExists($pidMySQL) Then
ProcessClose($pidMySQL)
_Log("MySQL已强制终止")
Else
_Log("MySQL已正常停止")
endif
$pidMySQL = 0
endif
GUICtrlSetData($hStatus, "服务状态: 已停止")
_Log("===== 所有服务已停止 =====")
EndFunc; 运行主函数
_Main()
然后使用下载得Autolt下的Aut2exe_x64.exe把AppLauncher.au3打包成exe
5.Setup.iss
; 应用程序安装脚本
[Setup]
AppName=应用名称
AppVersion=1.0.0
; 设置固定安装路径,不允许用户更改
DefaultDirName=路径
; 禁用目录选择页面,强制使用默认路径
DisableDirPage=yes
DefaultGroupName=应用名称;安装程序输出路径
OutputDir=.\output
OutputBaseFilename=应用名称安装程序
***pression=lzma
Solid***pression=yes
PrivilegesRequired=admin
; 设置安装程序图标
SetupIconFile=./logo.ico
; 禁用"选择开始菜单文件夹"页面,使用默认组名
DisableProgramGroupPage=yes[Languages]
Name: "chinese"; MessagesFile: "***piler:Default.isl"[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked[Files]
; 前端文件
Source: ".\frontend\*"; DestDir: "{app}\frontend"; Flags: recursesubdirs createallsubdirs
; 数据同步文件这个不需要可以删掉
Source: ".\dbsyncer\*"; DestDir: "{app}\dbsyncer"; Flags: recursesubdirs createallsubdirs
; 后端文件
Source: ".\backend\app.jar"; DestDir: "{app}\backend"
; JRE
Source: ".\jre\*"; DestDir: "{app}\jre"; Flags: recursesubdirs createallsubdirs
; Redis
Source: ".\redis\*"; DestDir: "{app}\redis"; Flags: recursesubdirs createallsubdirs
; MySQL
Source: ".\mysql\*"; DestDir: "{app}\mysql"; Flags: recursesubdirs createallsubdirs
; Nginx
Source: ".\nginx\*"; DestDir: "{app}\nginx"; Flags: recursesubdirs createallsubdirs
; 启动程序
Source: ".\AppLauncher.exe"; DestDir: "{app}"
; 包含图标文件
Source: "logo.ico"; DestDir: "{app}"; Flags: ignoreversion ;[Icons]
; 设置开始菜单快捷方式图标
Name: "{group}\应用名称"; Filename: "{app}\AppLauncher.exe"; IconFilename: "{app}\logo.ico"
; 设置桌面快捷方式图标
Name: "{***mondesktop}\应用名称"; Filename: "{app}\AppLauncher.exe"; IconFilename: "{app}\logo.ico"; Tasks: desktopicon
; 添加卸载程序快捷方式
Name: "{group}\卸载应用名称"; Filename: "{uninstallexe}"[Run]
Filename: "{app}\AppLauncher.exe"; Description: "{cm:LaunchProgram,应用名称}"; Flags: nowait postinstall skipifsilent[UninstallDelete]
Type: filesandordirs; Name: "{app}"[UninstallRun]
Filename: "{app}\mysql\bin\mysqladmin.exe"; Parameters: "-u root shutdown"; WorkingDir: "{app}\mysql\bin"; Flags: waituntilterminated
Filename: "{app}\redis\redis-cli.exe"; Parameters: "shutdown"; WorkingDir: "{app}\redis"; Flags: waituntilterminated
6.DBsyncer数据同步服务 安装使用教程
玩转开源数据同步中间件Dbsyncer,这一篇就够了-CSDN博客
初始化数据库
运行AppLauncher.exe启动起来,启动成功后在\mysql\bin下进入cmd窗口
执行mysql -u root -p 然后输入密码root 然后创建数据库CREATE DATABASE 数据库名称;
然后选择数据库use 数据库名称 然后执行sql文件SOURCE 你的sql文件绝对路径\你的sql文件.sql;(转储sql文件)
数据库初始化完成后
打包
使用下载的inner setup对Setup.iss进行打包
安装完成之后,双击快捷方式打开。