Files
lijing ec1f94eaa8
build / build (push) Successful in 10m17s
feat: 提交校园公告前端工程源码(Vue3 + Vite + view-ui-plus)
- 同步仓库 CI 配置 .gitea/workflows/build.yml
- 纳入 src/public/config/scripts 等工程文件
- .gitignore 增加 .scratch/.backup/.trash,排除本地临时产物
2026-09-15 11:15:03 +08:00

123 lines
4.1 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.
<#
.SYNOPSIS
根据端口号查找并结束占用它的进程,释放端口。
.DESCRIPTION
默认只处理处于 LISTEN(监听)状态、占用该端口的进程。
会先列出进程 PID / 名称 / 命令行,确认后再结束(-Force 可跳过确认)。
结束后自动复查端口是否已释放。优先用 Get-NetTCPConnection,
不可用时回退解析 netstat -ano。
.PARAMETER Port
要释放的端口号(1-65535)。
.PARAMETER Force
跳过交互确认,直接结束进程。
.PARAMETER IncludeClient
连同“已连接到该端口”的客户端进程一起处理(默认只看服务端监听进程)。
.EXAMPLE
.\kill-port.ps1 8101
.EXAMPLE
.\kill-port.ps1 -Port 8101 -Force
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[ValidateRange(1, 65535)]
[int]$Port,
[switch]$Force,
[switch]$IncludeClient
)
$ErrorActionPreference = 'Stop'
function Get-PortPids {
param([int]$Port, [bool]$IncludeClient)
$pids = @()
try {
if ($IncludeClient) {
$conns = Get-NetTCPConnection -LocalPort $Port -ErrorAction Stop
}
else {
$conns = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction Stop
}
$pids = @($conns | Select-Object -ExpandProperty OwningProcess -Unique)
}
catch {
# 回退:解析 netstat -ano
$lines = netstat -ano | Select-String -Pattern (":{0}\s" -f $Port)
foreach ($l in $lines) {
if (-not $IncludeClient -and ($l.Line -notmatch 'LISTENING')) { continue }
$parts = ($l.Line -split '\s+') | Where-Object { $_ }
$p = $parts[-1]
if ($p -match '^\d+$') { $pids += [int]$p }
}
$pids = @($pids | Select-Object -Unique)
}
return $pids
}
Write-Host "查询占用端口 $Port 的进程 ..." -ForegroundColor Cyan
$pids = @(Get-PortPids -Port $Port -IncludeClient $IncludeClient.IsPresent)
if (-not $pids) {
Write-Host "端口 $Port 当前没有被任何进程占用,无需处理。" -ForegroundColor Green
return
}
$myPid = $PID
$rows = foreach ($procId in $pids) {
$proc = Get-CimInstance Win32_Process -Filter "ProcessId=$procId" -ErrorAction SilentlyContinue
[pscustomobject]@{
PID = $procId
Name = if ($proc) { $proc.Name } else { '(已退出)' }
CmdLine = if ($proc) { $proc.CommandLine } else { '' }
}
}
$rows | Format-Table -AutoSize PID, Name
foreach ($r in $rows) {
if ($r.CmdLine) { Write-Host " [$($r.PID)] $($r.CmdLine)" -ForegroundColor DarkGray }
}
# 过滤掉系统空闲进程(0)与脚本自身
$targets = $rows | Where-Object { $_.PID -ne 0 -and $_.PID -ne $myPid }
if (-not $targets) {
Write-Host "没有可安全结束的进程(均为系统进程或脚本自身)。" -ForegroundColor Yellow
return
}
if (-not $Force) {
# 非交互(stdin 被管道/重定向接管)时绝不自动杀进程,必须显式 -Force
$interactive = -not ([Console]::IsInputRedirected -or -not [Environment]::UserInteractive)
if (-not $interactive) {
Write-Host "非交互环境且未指定 -Force,已取消(不会结束任何进程)。要直接释放请加 -Force。" -ForegroundColor Yellow
return
}
$ans = Read-Host "确认结束以上 $($targets.Count) 个进程并释放端口 $Port ? (y/N)"
if ($ans -notmatch '^[Yy]') { Write-Host "已取消。" -ForegroundColor Yellow; return }
}
foreach ($t in $targets) {
try {
Stop-Process -Id $t.PID -Force -ErrorAction Stop
Write-Host "已结束 PID $($t.PID) ($($t.Name))" -ForegroundColor Green
}
catch {
Write-Host "结束 PID $($t.PID) 失败:$($_.Exception.Message)" -ForegroundColor Red
}
}
Start-Sleep -Milliseconds 500
$remain = @(Get-PortPids -Port $Port -IncludeClient $false)
if ($remain) {
Write-Host "端口 $Port 仍被占用:PID $($remain -join ', ')(可能是系统进程或权限不足,试试以管理员身份运行)" -ForegroundColor Red
exit 1
}
else {
Write-Host "端口 $Port 已释放 OK" -ForegroundColor Green
}