2025-08-18 18:53:06 +08:00

575 lines
19 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!PowerShell
######################################################################
# Function
# CreateTime: 2025-08-06 12:52:28
# Author: Yue Jiajun
# Version: 0.1.8
# Write-Host 是否输出
# false: 打包成 exe 时,需要设置为 false
# true: 直接运行 ps1时可以为 true
$outputWriteHost = $false
$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"
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
}
if (-not (Test-Path -Path $FilePath)) {
[System.IO.File]::WriteAllText($FilePath, "", [System.Text.Encoding]::UTF8)
}
[System.IO.File]::AppendAllText($FilePath, "$Content`r`n", [System.Text.Encoding]::UTF8)
}
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."
}
}
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#20250810! -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."
}
}
catch {
Write-Log "Error importing $($sqlFile.Name):$_"
}
}
}
Write-Log "All script processing has been completed."
}
}
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
}
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
}
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 {
if (-not $env:JDK_21) {
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
}
if (-not $env:MODEL_MANAGE_DB_SERVER) {
$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
}
if (-not $env:MODEL_MANAGE_DB_PORT) {
$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
}
if (-not $env:MODEL_MANAGE_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 {
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
Get-Process -Name $NGINX_EXE.Replace(".exe", "") -ErrorAction SilentlyContinue | Stop-Process -Force
$NGINX_PATH = $NGINX_EXE
if (-not $NGINX_PATH) {
# $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_CONFIG = "$MAIN_PATH\conf\web.conf"
$NGINX_CONFIG = "conf\web.conf"
if (-not $NGINX_CONFIG) {
# $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
$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
"@
# 以 ANSI 写入文件 temp.vbsvbs 脚本不能使用 utf-8
$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"
Start-Sleep -Seconds 1
Remove-Item "temp.vbs" -Force
}
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
}
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.password=Wfbke8!LeMY5Fwwe -Dproject.database-ip=$env:MODEL_MANAGE_DB_SERVER -Dproject.database-port=$env:MODEL_MANAGE_DB_PORT $env:MODEL_VM_PARAMS"
$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) {
Write-Host "$($env:JDK_21)\bin\java.exe" $argumentList -jar "$env:MODEL_MANAGE_BIN"
}
$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
$argumentList += "-jar"
$argumentList += "`"$env:MODEL_MANAGE_BIN`""
$process = Start-Process `
-FilePath "$($env:JDK_21)\bin\java.exe" `
-ArgumentList $argumentList `
-WindowStyle Hidden `
-RedirectStandardOutput "NUL" `
-RedirectStandardError "NUL_ERR" `
-PassThru
if ($process) {
Write-Host "进程已启动PID: $($process.Id)"
} else {
Write-Host "进程启动失败!"
}
}
# 检查并启动 MySQL 数据库
Check-With-Start-MySQL
Start-Sleep -Seconds 2
# 导入数据
Import-Script "127.0.0.1" "33306" "root" "Root@2025"
Start-Sleep -Seconds 1
# 检查 Web 运行环境
Check-Web
# 启动 Nginx 服务
Start-Web
# 启动 MinIO 服务
Start-MinIO
Start-Sleep -Seconds 1
# 检查 SpringBoot 运行环境
Check-SpringBoot
# 启动 SpringBoot 服务
Start-SpringBoot
Write-Host "已启动模型"
Start-Sleep -Seconds 3