Files
yanpeng200212 dbe8463064 IIS 发布目录改为项目外的独立目录 C:\F9WebAiTest-IIS
- deploy-iis.ps1 / update-iis.ps1 的发布路径由项目内 publish 改为 C:\F9WebAiTest-IIS
- 站点物理路径已切换并验证,发布物与代码目录分离,便于测试与备份
2026-10-12 14:40:41 +08:00

113 lines
5.4 KiB
PowerShell
Raw Permalink 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.
# ============================================================
# 将「智慧缫丝系统」(f9-web-ai-test) 发布到本机 IIS
# - 自动安装 ASP.NET Core Hosting Bundle(IIS 托管 .NET 8 必需)
# - 创建应用池 / 站点 / 目录权限,并做一次自检
# 必须以【管理员身份】运行
# ============================================================
$ErrorActionPreference = 'Stop'
# 全过程写入日志文件,便于提权窗口关闭后回看
$logDir = Join-Path $PSScriptRoot '_runlog'
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
try { Start-Transcript -Path (Join-Path $logDir 'deploy-iis.log') -Force -ErrorAction Stop | Out-Null } catch { }
# 发布物放在项目外的独立目录,与代码分离(便于测试与备份)
$publishDir = 'C:\F9WebAiTest-IIS'
$siteName = 'F9WebAiTest'
$appPoolName = 'F9WebAiTest'
$preferredPort = 80
$ancmPath = 'C:\Program Files\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll'
$hostingBundle = 'https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/8.0.21/dotnet-hosting-8.0.21-win.exe'
$installer = Join-Path $env:TEMP 'dotnet-hosting-8.0.21-win.exe'
function Info($m) { Write-Host "[部署] $m" -ForegroundColor Cyan }
function Warn($m) { Write-Host "[警告] $m" -ForegroundColor Yellow }
# ---------- 0. 前置校验 ----------
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw '请以管理员身份运行本脚本'
}
if (-not (Test-Path $publishDir)) { throw "发布目录不存在:$publishDir" }
if (-not (Test-Path (Join-Path $publishDir 'wwwroot\index.html'))) { throw "前端产物缺失:$publishDir\wwwroot\index.html" }
if (-not (Test-Path (Join-Path $publishDir 'F9WebAiTest.Api.dll'))) { throw "后端产物缺失:$publishDir\F9WebAiTest.Api.dll" }
if (-not (Test-Path 'C:\Windows\System32\inetsrv\appcmd.exe')) { throw '本机未安装 IIS,请先启用 IIS 功能' }
Import-Module WebAdministration
# ---------- 1. ASP.NET Core Hosting Bundle ----------
if (-not (Test-Path $ancmPath)) {
Info '未检测到 AspNetCoreModuleV2,开始下载 Hosting Bundle 8.0.21 ...'
Invoke-WebRequest -Uri $hostingBundle -OutFile $installer -UseBasicParsing
Info '下载完成,静默安装中(约 1-2 分钟)...'
Start-Process -FilePath $installer -ArgumentList '/install', '/quiet', '/norestart' -Wait
if (-not (Test-Path $ancmPath)) { throw 'Hosting Bundle 安装失败,请手动安装后重试' }
Info '安装完成,重启 IIS 使模块生效 ...'
& iisreset /noforce | Out-Null
} else {
Info 'AspNetCoreModuleV2 已安装,跳过'
}
# ---------- 2. 选择端口 ----------
$port = $preferredPort
$occupied = netstat -ano | Select-String 'LISTENING' | Select-String ":$port\s"
if ($occupied) {
$port = 8080
Warn "端口 $preferredPort 已被占用,改用 $port"
}
# ---------- 3. 应用池(无托管代码,与 .NET Core 应用匹配)----------
if (Test-Path "IIS:\AppPools\$appPoolName") {
Info "应用池 $appPoolName 已存在,更新配置"
} else {
New-WebAppPool -Name $appPoolName | Out-Null
Info "已创建应用池 $appPoolName"
}
Set-ItemProperty "IIS:\AppPools\$appPoolName" -Name managedRuntimeVersion -Value ''
Set-ItemProperty "IIS:\AppPools\$appPoolName" -Name startMode -Value 'AlwaysRunning'
# ---------- 4. 站点 ----------
if (Test-Path "IIS:\Sites\$siteName") {
Info "站点 $siteName 已存在,更新物理路径与应用池"
Set-ItemProperty "IIS:\Sites\$siteName" -Name physicalPath -Value $publishDir
Set-ItemProperty "IIS:\Sites\$siteName" -Name applicationPool -Value $appPoolName
if (-not (Get-WebBinding -Name $siteName -Protocol http -Port $port -ErrorAction SilentlyContinue)) {
New-WebBinding -Name $siteName -Protocol http -Port $port -IPAddress '*'
Info "已补充绑定 http://*:$port"
}
} else {
New-Website -Name $siteName -PhysicalPath $publishDir -Port $port -ApplicationPool $appPoolName -Force | Out-Null
Info "已创建站点 $siteName"
}
# ---------- 5. 目录权限(应用池身份需读写:SQLite 库文件、日志)----------
$aclUser = "IIS AppPool\$appPoolName"
& icacls $publishDir /grant "${aclUser}:(OI)(CI)M" /T /Q | Out-Null
Info "已授予 $aclUser 读写权限"
# ---------- 6. 启动 ----------
if ((Get-WebAppPoolState -Name $appPoolName).Value -ne 'Started') { Start-WebAppPool -Name $appPoolName }
if ((Get-Website -Name $siteName).State -ne 'Started') { Start-Website -Name $siteName }
Start-Sleep -Seconds 4
# ---------- 7. 自检 ----------
$url = "http://localhost:$port/"
Info '开始自检 ...'
try {
$r = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 40
Info "首页:HTTP $($r.StatusCode)(前端已托管)"
} catch {
Warn "首页访问失败:$($_.Exception.Message)"
Warn "如为 500,请查看 事件查看器 → Windows 日志 → 应用程序,或打开 $publishDir\web.config 把 stdoutLogEnabled 改为 true 后重试"
}
try {
$login = Invoke-RestMethod -Uri "${url}api/auth/login" -Method Post -ContentType 'application/json' `
-Body '{"userName":"admin","password":"123456"}' -TimeoutSec 40
Info "登录接口:code=$($login.code) $($login.message)"
} catch {
Warn "登录接口调用失败:$($_.Exception.Message)"
}
Write-Host ''
Info "部署完成,访问地址:$url"
Info "API 文档:${url}swagger 默认账号:admin / 123456"