Files

147 lines
4.0 KiB
PowerShell

<#
.SYNOPSIS
启动支持网页命令输入的串口实时控制台。
.DESCRIPTION
使用单一进程独占串口,同时提供串口读取、原始日志、时间戳文本日志和本机网页命令接口。
网页仅监听 127.0.0.1;普通命令支持 None、CR、LF、CRLF 四种结尾。
.EXAMPLE
.\serial_web_console.ps1 -Port COM56 -LogPath F:\tmp\serial.log
.EXAMPLE
.\serial_web_console.ps1 -Port COM56 -LogPath .\serial.log -WebPort 8766
.PARAMETER ValidateOnly
只编译并验证程序和页面资源,不打开串口,也不监听网页端口。
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Port,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$LogPath,
[ValidateRange(1, 4000000)]
[int]$BaudRate = 115200,
[ValidateRange(5, 8)]
[int]$DataBits = 8,
[ValidateSet('None', 'Odd', 'Even', 'Mark', 'Space')]
[string]$Parity = 'None',
[ValidateSet('One', 'OnePointFive', 'Two')]
[string]$StopBits = 'One',
[ValidateSet('None', 'XOnXOff', 'RequestToSend', 'RequestToSendXOnXOff')]
[string]$Handshake = 'None',
[string]$EncodingName = 'utf-8',
[ValidateRange(1, 5000)]
[int]$PollMilliseconds = 100,
[ValidateRange(64, 1048576)]
[int]$BufferSize = 4096,
[string]$RawPath,
[ValidateRange(1024, 65535)]
[int]$WebPort = 8766,
[string]$HtmlPath,
[ValidateRange(0, 2147483647)]
[int]$DurationSeconds = 0,
[switch]$DtrEnable,
[switch]$RtsEnable,
[switch]$ValidateOnly
)
$ErrorActionPreference = 'Stop'
$broker = $null
try {
if ($PSVersionTable.PSEdition -ne 'Desktop') {
throw '该脚本需要由 Windows PowerShell 5.1 运行。请使用 powershell.exe,而不是 pwsh.exe。'
}
$sourcePath = Join-Path $PSScriptRoot 'SerialWebConsoleHost.cs'
if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
throw "找不到串口服务源文件:$sourcePath"
}
if ([string]::IsNullOrWhiteSpace($HtmlPath)) {
$HtmlPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'assets\serial-console.html'
}
$resolvedHtmlPath = [System.IO.Path]::GetFullPath($HtmlPath)
if (-not (Test-Path -LiteralPath $resolvedHtmlPath -PathType Leaf)) {
throw "找不到串口控制台页面:$resolvedHtmlPath"
}
# Windows PowerShell 5.1 自带完整 .NET Framework,可直接编译 SerialPort 和 HttpListener。
Add-Type -Path $sourcePath -ErrorAction Stop
if ($ValidateOnly.IsPresent) {
Write-Output "验证通过:串口服务代码已编译,网页资源存在。"
Write-Output "源文件:$sourcePath"
Write-Output "页面:$resolvedHtmlPath"
return
}
$resolvedLogPath = [System.IO.Path]::GetFullPath($LogPath)
if ([string]::IsNullOrWhiteSpace($RawPath)) {
$resolvedRawPath = $resolvedLogPath + '.raw.bin'
}
else {
$resolvedRawPath = [System.IO.Path]::GetFullPath($RawPath)
}
$broker = [EmbeddedAppPcDebug.SerialWebConsoleHost]::new(
$Port,
$BaudRate,
$DataBits,
$Parity,
$StopBits,
$Handshake,
$EncodingName,
$PollMilliseconds,
$BufferSize,
$DtrEnable.IsPresent,
$RtsEnable.IsPresent,
$resolvedLogPath,
$resolvedRawPath,
$WebPort,
$resolvedHtmlPath
)
$broker.Start()
$startTime = Get-Date
Write-Output "串口网页控制台已启动:$($broker.Url)"
Write-Output "按 Ctrl+C 可停止串口采集和网页服务。"
while (-not $broker.IsStopping) {
if ($DurationSeconds -gt 0 -and ((Get-Date) - $startTime).TotalSeconds -ge $DurationSeconds) {
break
}
Start-Sleep -Milliseconds 200
}
}
catch {
$message = '[' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff') + '] 串口网页控制台失败:' + [string]$_.Exception.Message
[Console]::Error.WriteLine($message)
exit 1
}
finally {
if ($null -ne $broker) {
$broker.Dispose()
}
}