623 lines
21 KiB
PowerShell
Raw Normal View History

2025-08-18 17:09:36 +08:00
#!PowerShell
######################################################################
# Function
# CreateTime: 2025-08-06 12:52:28
# Author: Yue Jiajun
# Version: 0.0.68
# Write-Host 是否输出
# false: 打包成 exe 时,需要设置为 false
# true: 直接运行 ps1时可以为 true
$outputWriteHost = $true
$outputLogFile = "$MAIN_PATH\startup.log"
$outputErrorFile = "$MAIN_PATH\error.log"
######################################################################
# Get current path
$MAIN_PATH = Get-Location
# Get database service name
$SERVER_NAME = $env:X_MANAGE_DB_SC
# Nginx executable name
$NGINX_EXE = "model-web.exe"
$logFile = "debug.log"
2025-08-18 17:09:36 +08:00
# Log recording function
function Write-Log {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] $message"
# [debug]
2025-08-18 17:09:36 +08:00
# Write-Output $logMessage | Out-File -FilePath $logFile -Append
Write-Host $logMessage
}
function randomText {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.ToCharArray()
$length = 12
$random = New-Object System.Random
$string = -join (1..$length | ForEach-Object { $chars[$random.Next(0, $chars.Length)] })
return $string
}
function Import-Script {
param (
[string]$dbServer,
[string]$dbPort,
[string]$dbUser,
[string]$dbPassword
)
# Check whether the script folder exists in the current path
if (Test-Path -Path ".\script" -PathType Container) {
Write-Log "Found script folder, starting to process .."
# Get all subfolders
$subFolders = Get-ChildItem -Path ".\script" -Directory
if ($subFolders.Count -eq 0) {
Write-Log "There are no subfolders in the script folder, skipping processing."
exit
}
# Traverse each subfolder
foreach ($folder in $subFolders) {
Write-Log "Database connection parameters - Please modify according to the actual situation $($folder.Name)"
# Get all RAR files under this folder
$rarFiles = Get-ChildItem -Path $folder.FullName -Filter "*.rar"
if ($rarFiles.Count -eq 0) {
Write-Log "There are no SQL files in the folder $($folder.Name), skipping."
continue
}
# Process each SQL file
foreach ($rarFile in $rarFiles) {
Write-Log "Processing file: $($rarFile.Name) (located in $($folder.Name))"
$rarName = $rarFile.BaseName
$rarDirectoryName = (Get-Item $rarFile.FullName).DirectoryName
try {
Start-Process -FilePath "rar" -ArgumentList "x -pshzyh!234 `"$($rarFile.FullName)`" `"$rarDirectoryName`"" -NoNewWindow -Wait
# Remove rar-file
if (Test-Path $rarFile.FullName) {
Remove-Item $rarFile.FullName -Force
# [debug]
# Write-Log "File deleted."
} else {
# [debug]
# Write-Log "File does not exist."
}
2025-08-18 17:09:36 +08:00
}
catch {
Write-Log "Error unrar $($rarFile.Name):$_"
}
}
}
# Traverse each subfolder
foreach ($folder in $subFolders) {
Write-Log "Database connection parameters - Please modify according to the actual situation $($folder.Name)"
# Get all SQL files under this folder
$sqlFiles = Get-ChildItem -Path $folder.FullName -Filter "*.sql"
if ($sqlFiles.Count -eq 0) {
Write-Log "There are no SQL files in the folder $($folder.Name), skipping."
continue
}
# Process each SQL file
foreach ($sqlFile in $sqlFiles) {
Write-Log "Processing file: $($sqlFile.Name) (located in $($folder.Name))"
# Use file name as database name (without extension)
$dbName = $sqlFile.BaseName
try {
# Connect to the database and execute SQL files
Write-Log "Creating database $dbName and importing $($sqlFile.Name)"
# Here we use MySQL client as an example. If it is SQL Server, please modify it to the corresponding command
# For SQL Server, you can use sqlcmd or Invoke sqlcmd
# $command = "mysql -h$dbServer -u$dbUser -p$dbPassword -P$dbPort -e 'CREATE DATABASE IF NOT EXISTS $dbName;'"
# Invoke-Expression $command
# $command = "mysql -h$dbServer -u$dbUser -p$dbPassword -P$dbPort $dbName `< `"$($sqlFile.FullName)`""
$command = "mysql -h$dbServer -u$dbUser -p$dbPassword -P$dbPort $($folder.Name) `< `"$($sqlFile.FullName)`""
# [debug]
# Write-Log $command
# Invoke-Expression $command # ERROR
# cmd /c $command # SUCCESS, WARN: >> CategoryInfo: NotSpecified: (mysql: [Warning...an be insecure.:String) [], RemoteException
# Get-Content $sqlFile.FullName | Invoke-Expression $command # ERROR
Start-Process -FilePath "mysql" -ArgumentList "-h$dbServer -u$dbUser -p$dbPassword -P$dbPort $($folder.Name)" -RedirectStandardInput $sqlFile.FullName -NoNewWindow -Wait
# Write-Log "Successfully imported $($sqlFile.Name) into database $dbName"
Write-Log "Successfully imported $($sqlFile.Name) into database $($folder.Name)"
$date = $(Get-Date -Format "yyyy-MM-dd")
$random = randomText
$target = ".\patch\$($date)"
New-Item -Path "$target" -ItemType Directory -Force
# cmd /c rar a -pPassword -hp "target.rar" "file"
# Start-Process -FilePath "rar" -ArgumentList "a -pPassword -hp "target.rar" "file"" -NoNewWindow -Wait
# Start-Process -FilePath "rar" -ArgumentList 'a', '-pPassword', '-hpPassword', 'target.rar', 'file' -NoNewWindow -Wait
Start-Process -FilePath "rar" -ArgumentList "a -pPassword#$($date)! -hp $target\$($random).rar `"$($sqlFile.FullName)`"" -NoNewWindow -Wait
# Remove script-file
if (Test-Path $sqlFile.FullName) {
Remove-Item $sqlFile.FullName -Force
# [debug]
# Write-Log "File deleted."
} else {
# [debug]
# Write-Log "File does not exist."
}
2025-08-18 17:09:36 +08:00
}
catch {
Write-Log "Error importing $($sqlFile.Name):$_"
}
}
}
Write-Log "All script processing has been completed."
}
}
function Append-Utf8NoBomContent {
param (
[Parameter(Mandatory=$true)]
[string]$FilePath,
[Parameter(Mandatory=$true)]
[string]$Content
)
# 确保目录存在,如果不存在则创建
$directory = [System.IO.Path]::GetDirectoryName($FilePath)
if (-not [System.IO.Directory]::Exists($directory)) {
New-Item -ItemType Directory -Path $directory -Force | Out-Null
}
# 使用 UTF-8无 BOM追加内容
# 需要PowerShell 6+
# $Content | Out-File -FilePath $FilePath -Append -Encoding utf8NoBOM
# 检查文件是否存在,如果不存在则先创建一个空文件(避免 BOM 问题)
if (-not (Test-Path -Path $FilePath)) {
# 使用 .NET 创建空文件(无 BOM
[System.IO.File]::WriteAllText($FilePath, "", [System.Text.Encoding]::UTF8)
}
# 使用 .NET 方法追加内容UTF-8 无 BOM
[System.IO.File]::AppendAllText($FilePath, "$Content`r`n", [System.Text.Encoding]::UTF8)
}
function Go-Home {
if($outputWriteHost) {
Write-Host ""
Write-Host "Exit ..."
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 任务执行完成"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
Start-Sleep -Seconds 5
exit 0
2025-08-18 17:09:36 +08:00
}
function Usage-MySQL {
if($outputWriteHost) {
Write-Host "ERROR: Please configure value in the system environment variable."
Write-Host "env: - X_MANAGE_DB_EXE"
Write-Host " - X_MANAGE_DB_COF"
Write-Host "skip database"
Write-Host ""
}
pause
Go-Home
2025-08-18 17:09:36 +08:00
}
function Usage-SpringBoot {
if($outputWriteHost) {
Write-Host "ERROR: Please configure `"JDK_21`" in the system environment variable."
}
pause
Go-Home
}
function Install-MySQL-Server {
# Check required environment variables
if (-not $env:X_MANAGE_DB_EXE) {
if($outputWriteHost) {
Write-Host "Error: Missing parameter! {X_MANAGE_DB_EXE}" | Out-File "error.log" -Append
}
Usage-MySQL
return
}
if (-not (Test-Path $env:X_MANAGE_DB_EXE)) {
if($outputWriteHost) {
Write-Host "Error: Missing parameter! {X_MANAGE_DB_EXE}" | Out-File "error.log" -Append
}
Usage-MySQL
return
}
Write-Host "exe: $($env:X_MANAGE_DB_EXE)"
$DB_EXEC = $env:X_MANAGE_DB_EXE
if (-not $env:X_MANAGE_DB_COF) {
if($outputWriteHost) {
Write-Host "Error: Missing parameter! {X_MANAGE_DB_COF}" | Out-File "error.log" -Append
}
Usage-MySQL
return
}
if (-not (Test-Path $env:X_MANAGE_DB_COF)) {
if($outputWriteHost) {
Write-Host "Error: Missing parameter! {X_MANAGE_DB_COF}" | Out-File "error.log" -Append
}
Usage-MySQL
return
}
if($outputWriteHost) {
Write-Host "ini: $($env:X_MANAGE_DB_COF)"
}
$DB_CONF = $env:X_MANAGE_DB_COF
# Install MySQL service
& $DB_EXEC --install $SERVER_NAME --defaults-file="$DB_CONF"
# Configure service to start automatically
sc.exe config $SERVER_NAME start= auto
# Wait for service registration
Start-Sleep -Seconds 1
# Start the service
Start-Service -Name $SERVER_NAME
# Wait for service to start
Start-Sleep -Seconds 1
}
function Check-With-Start-MySQL {
# Check if service exists
$service = Get-Service -Name $SERVER_NAME -ErrorAction SilentlyContinue
if ($service) {
# Service exists, check if running
if ($service.Status -eq "Running") {
if($outputWriteHost) {
Write-Host "database ok."
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 数据已运行..."
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
} else {
# Start the service if not running
if($outputWriteHost) {
Write-Host "start up ..."
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 启动数据库中..."
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
Start-Service -Name $SERVER_NAME
}
} else {
# Install MySQL service
Install-MySQL-Server
}
}
function Check-Web {
# 检查
}
function Check-SpringBoot {
# 检查 JDK_21 环境变量
if (-not $env:JDK_21) {
# 如果不存在,则检查安装目录下是否存在 java 可执行文件
if (Test-Path "$MAIN_PATH\jre\bin\java.exe") {
$env:JDK_21 = "$MAIN_PATH\jre"
if($outputWriteHost) {
Write-Host "ONESELF"
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - JDK_21 环境变量不存在,默认生效: $env:JDK_21"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
}
}
if (-not $env:JDK_21) {
Usage-SpringBoot
return
}
# 检查连接 DB 的 IP 地址
if (-not $env:MODEL_MANAGE_DB_SERVER) {
# 不存在,则默认 127
$env:MODEL_MANAGE_DB_SERVER = "127.0.0.1"
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - MODEL_MANAGE_DB_SERVER 环境变量不存在,默认生效: $env:MODEL_MANAGE_DB_SERVER"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
}
# 检查连接 DB 的端口号
if (-not $env:MODEL_MANAGE_DB_PORT) {
# 不存在,则默认 3306
$env:MODEL_MANAGE_DB_PORT = "3306"
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - MODEL_MANAGE_DB_PORT 环境变量不存在,默认生效: $env:MODEL_MANAGE_DB_PORT"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
}
# 检查 SpringBoot 启动 jar 文件环境变量
if (-not $env:MODEL_MANAGE_BIN) {
# 不存在,则默认安装目录下 bin
$env:MODEL_MANAGE_BIN = "$MAIN_PATH\bin\demo-0.0.1.jar"
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - MODEL_MANAGE_BIN 环境变量不存在,默认生效: $env:MODEL_MANAGE_BIN"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
if (-not $env:MODEL_MANAGE_BIN) {
if($outputWriteHost) {
Write-Host "ERROR: Missing executable jar"
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 缺少可执行的 jar"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
pause
Go-Home
}
}
if($outputWriteHost) {
Write-Host "jdk ok."
Write-Host ""
}
Start-Sleep -Seconds 1
}
function Start-Web {
# 进入 web 下
Set-Location "$MAIN_PATH\web"
if($outputWriteHost) {
Write-Host "Start Web ..."
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 准备Web启动..."
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# Kill existing web service processes
Get-Process -Name $NGINX_EXE.Replace(".exe", "") -ErrorAction SilentlyContinue | Stop-Process -Force
# 配置默认启动参数
$NGINX_PATH = $NGINX_EXE
if (-not $NGINX_PATH) {
# 不存在,则默认安装目录下 nginx.exe
# $NGINX_PATH = "$MAIN_PATH\nginx.exe"
$NGINX_PATH = "nginx.exe"
if (-not $NGINX_PATH) {
if($outputWriteHost) {
Write-Host "ERROR: Missing executable web."
}
pause
Go-Home
}
}
if($outputWriteHost) {
Write-Host "$NGINX_PATH"
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Web生效可执行器 $NGINX_PATH"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# 检查 Nginx 配置文件是否存在,优先使用 web.conf
# $NGINX_CONFIG = "$MAIN_PATH\conf\web.conf"
$NGINX_CONFIG = "conf\web.conf"
if (-not $NGINX_CONFIG) {
# 不存在,则默认安装目录下 nginx.conf
# $NGINX_CONFIG = "$MAIN_PATH\conf\nginx.conf"
$NGINX_CONFIG = "conf\nginx.conf"
if (-not $NGINX_CONFIG) {
if($outputWriteHost) {
Write-Host "ERROR: Missing web config"
}
pause
Go-Home
}
}
if($outputWriteHost) {
Write-Host "$NGINX_CONFIG"
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Web配置生效文件 $NGINX_CONFIG"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# 创建以管理员身份运行的 VBS脚本类似于原始的批处理方式
$vbsContent = @"
Set UAC = CreateObject("Shell.Application")
Set WshShell = CreateObject("WScript.Shell")
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set tempFile = fso.OpenTextFile("%SystemRoot%\System32\config\systemprofile", 1)
If Err.Number = 0 Then
WshShell.Run "$NGINX_PATH -c $NGINX_CONFIG", 0, False
Else
UAC.ShellExecute "$NGINX_PATH", "-c $NGINX_CONFIG", "", "runas", 0
End If
"@
# 以 UTF-8 写入文件 temp.vbs vbs 脚本不能使用 utf-8
# $vbsContent | Out-File -FilePath "$MAIN_PATH\web\temp.vbs" -Encoding UTF8
# 以 ANSI 写入文件 temp.vbs
$vbsContent | Out-File -FilePath "$MAIN_PATH\web\temp.vbs" -Encoding ASCII
if($outputWriteHost) {
Write-Host "Build temporary startup script web."
}
# 运行 vbs 并等待结束
# Start-Process "cscript.exe" -ArgumentList "//nologo temp.vbs" -Wait
# 不等待执行下一条命令Nginx 本身是持续性窗口,等待会导致阻塞
Start-Process "cscript.exe" -ArgumentList "//nologo temp.vbs"
# 等待1秒后防止上一条执行慢删除临时文件
Start-Sleep -Seconds 1
Remove-Item "temp.vbs" -Force
}
2025-08-18 18:53:06 +08:00
function Start-MinIO {
# 进入 minio 目录下
Set-Location "$MAIN_PATH"
Set-Location ".."
$WORKSPACE_PATH = Get-Location
Set-Location "io"
if($outputWriteHost) {
Write-Host "Start Minio ..."
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 准备启动 Minio..."
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# 停止现有的 minio 进程
Get-Process -Name "minio" -ErrorAction SilentlyContinue | Stop-Process -Force
# 配置默认启动参数
$MINIO_PATH = "minio.exe"
if (-not (Test-Path $MINIO_PATH)) {
if($outputWriteHost) {
Write-Host "Error: Cannot find minio.exe executable file."
}
pause
Go-Home
}
# 配置用户名和密码(可以改为从参数传入)
$MINIO_ROOT_USER = "minio_34KYwR" # 默认用户名
$MINIO_ROOT_PASSWORD = "minio_FEaTQx" # 默认密码
if($outputWriteHost) {
Write-Host "$MINIO_PATH"
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Minio executable file: $MINIO_PATH"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# Minio 配置参数
$MINIO_DATA_DIR = "data" # 数据目录
$MINIO_PORT = 9000 # API 端口
$MINIO_CONSOLE_PORT = 9001 # 控制台端口
# 创建以管理员身份运行的 VBS脚本
$vbsContent = @"
Set UAC = CreateObject("Shell.Application")
Set WshShell = CreateObject("WScript.Shell")
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set tempFile = fso.OpenTextFile("%SystemRoot%\System32\config\systemprofile", 1)
If Err.Number = 0 Then
WshShell.Run "cmd /c set MINIO_ROOT_USER=$MINIO_ROOT_USER && set MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD && $MINIO_PATH server $MINIO_DATA_DIR --console-address :$MINIO_CONSOLE_PORT", 0, False
Else
UAC.ShellExecute "cmd", "/c set MINIO_ROOT_USER=$MINIO_ROOT_USER && set MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD && $MINIO_PATH server $MINIO_DATA_DIR --console-address :$MINIO_CONSOLE_PORT", "", "runas", 0
End If
"@
# 以 ANSI 写入文件 temp.vbs
$vbsContent | Out-File -FilePath "$WORKSPACE_PATH\io\temp.vbs" -Encoding ASCII
if($outputWriteHost) {
Write-Host "Temporary startup script has been created."
}
# 运行 vbs 脚本
Start-Process "cscript.exe" -ArgumentList "//nologo temp.vbs"
# 等待1秒后删除临时文件
Start-Sleep -Seconds 1
Remove-Item "temp.vbs" -Force
# 输出访问信息
if($outputWriteHost) {
Write-Host "Minio:"
Write-Host "WEB: http://localhost:$MINIO_CONSOLE_PORT"
Write-Host "API: http://localhost:$MINIO_PORT"
Write-Host "user: $MINIO_ROOT_USER"
Write-Host "pass: $MINIO_ROOT_PASSWORD"
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Minio started successfully! Console port: $MINIO-CONSOLE-PORT, API port: $MINIO-PORT, username: $MINIO-COOT_USER"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
}
2025-08-18 17:09:36 +08:00
function Start-SpringBoot {
# 准备启动后台服务
Set-Location $MAIN_PATH
if($outputWriteHost) {
Write-Host "Start Server ..."
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 准备SpringBoot启动..."
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# jvm启动参数
# 指定环境变量 MODEL_MANAGE_DB_SERVER
# 指定环境变量 MODEL_MANAGE_DB_PORT
# 追加自定义JVM参数 MODEL_VM_PARAMS
$arguments = "-Dspring.profiles.active=dev,mysql" +
" -Dmybatis-flex.datasource.ds1.username=model" +
" -Dmybatis-flex.datasource.ds1.password=Wfbke8!LeMY5Fwwe" +
" -Dproject.database-ip=$env:MODEL_MANAGE_DB_SERVER" +
" -Dproject.database-port=$env:MODEL_MANAGE_DB_PORT" +
" $env:MODEL_VM_PARAMS "
2025-08-18 17:09:36 +08:00
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 启动JVM参数 $arguments"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# 拆分参数为数组
$argumentList = $arguments -split " -"
# 处理第一个元素(没有前导"-")和其余元素(添加前导"-"
$argumentList = @($argumentList[0]) + ($argumentList[1..($argumentList.Length-1)] | ForEach-Object { "-$_" })
# 构建最终的调用命令
if($outputWriteHost) {
# [debug]
# Write-Host "$($env:JDK_21)\bin\java.exe" $argumentList -jar "$env:MODEL_MANAGE_BIN"
2025-08-18 17:09:36 +08:00
}
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 启动完整命令: $($env:JDK_21)\bin\java.exe $argumentList -jar $env:MODEL_MANAGE_BIN"
Append-Utf8NoBomContent -FilePath $outputLogFile -Content $logMessage
# 启动 SpringBoot
& "$($env:JDK_21)\bin\java.exe" $argumentList -jar "$env:MODEL_MANAGE_BIN"
}
# 检查并启动 MySQL 数据库
Check-With-Start-MySQL
Start-Sleep -Seconds 2
# 导入数据
Import-Script "127.0.0.1" "33306" "root" "Root@2025"
# 检查 Web 运行环境
Check-Web
# 启动 Nginx 服务
Start-Web
Start-Sleep -Seconds 2
2025-08-18 18:53:06 +08:00
# 启动 MinIO 服务
Start-MinIO
Start-Sleep -Seconds 2
2025-08-18 17:09:36 +08:00
# 检查 SpringBoot 运行环境
Check-SpringBoot
# 启动 SpringBoot 服务
Start-SpringBoot
Write-Host "已启动模型"
Start-Sleep -Seconds 6