Skip to content

[Windows/PowerShell 7] supervisor-windows.ps1 无法 start/stop/status,桥接起不来(含修复) #114

Description

@hmzyly

现象

Windows + PowerShell 7(pwsh 7.x) 环境下,scripts/supervisor-windows.ps1start / stop / status 命令全部无法执行,桥接进程无法启动/管理。直接表现是:进程一旦退出就再也起不来,IM(如飞书)消息接不通。

环境:Windows 11,PowerShell 7.x(node v25),runtime=codex/claude 均复现。

下面 3 处问题,前两处可稳定复现并修复,第 3 处附带观察。


Bug 1 — 变量名 $pid / 参数 $Pid 与只读自动变量 $PID 冲突(致命)

PowerShell(5.1 和 7 都)有一个只读自动变量 $PID(当前进程 ID),变量名大小写不敏感。脚本里用了同名变量,赋值时直接抛错、命令中断:

Cannot overwrite variable PID because it is read-only or constant.

涉及位置(基于 main 分支 scripts/supervisor-windows.ps1):

  • param([string]$Pid)(约 L75)及函数体内的 $Pid(L76-77)
  • $pid = Start-Fallback(约 L270)
  • $pid = Read-Pid / if (-not $pid) / Test-PidAlive $pid / Stop-Process -Id ([int]$pid)(stop 分支,约 L297-300)
  • $pid = Read-Pid / if ($pid -and ...) / "PID: $pid"(status 分支,约 L310/318/319)

结果:startstopstatus 三个分支只要执行到 $pid 赋值就崩。

修复:把局部 $pid 改名为 $bridgePid,把函数参数 $Pid 改名为 $ProcId$existingPid / $newPid 不受影响,无需改)。


Bug 2 — Start-Process 把 stdout 与 stderr 重定向到同一文件(致命)

Start-Fallback 中(约 L228-229):

-RedirectStandardOutput $LogFile `
-RedirectStandardError  $LogFile `

PowerShell 7 下 Start-Process 不允许两个重定向指向同一文件,直接报错、进程无法拉起:

Start-Process: This command cannot be run because "RedirectStandardOutput" and
"RedirectStandardError" are same. Give different inputs and Run your command again.

修复:stderr 写到单独文件(仓库里 ~/.claude-to-im/logs/ 本就有 bridge-error.log):

# 顶部 Paths 区新增:
$ErrLogFile = Join-Path $CtiHome 'logs' 'bridge-error.log'

# Start-Fallback 内改为:
-RedirectStandardError $ErrLogFile `

Bug 3 — daemon.sh 在 Windows(git-bash) 下转发给 ps1 时位置参数错位(附带观察)

通过 bash scripts/daemon.sh {logs N|start|...} 调用时,转发到 supervisor-windows.ps1 报:

supervisor-windows.ps1 : 找不到接受实际参数"bridge.log"的位置形式参数
(PositionalParameterNotFound, ParameterBindingException)

看起来是 sh→ps1 的参数传递把日志文件路径当成了多余的位置参数。我本地暂以"直接用 pwsh -File scripts/supervisor-windows.ps1 <cmd>"绕过,未深入定位 daemon.sh 的转发逻辑,供参考。


建议的最小修复(针对 Bug 1 + Bug 2)

@@ Paths
 $LogFile    = Join-Path $CtiHome 'logs' 'bridge.log'
+$ErrLogFile = Join-Path $CtiHome 'logs' 'bridge-error.log'

@@ Test-PidAlive
-function Test-PidAlive {
-    param([string]$Pid)
-    if (-not $Pid) { return $false }
-    try { $null = Get-Process -Id ([int]$Pid) -ErrorAction Stop; return $true }
+function Test-PidAlive {
+    param([string]$ProcId)
+    if (-not $ProcId) { return $false }
+    try { $null = Get-Process -Id ([int]$ProcId) -ErrorAction Stop; return $true }
     catch { return $false }
 }

@@ Start-Fallback
         -RedirectStandardOutput $LogFile `
-        -RedirectStandardError $LogFile `
+        -RedirectStandardError $ErrLogFile `

@@ start 分支
-            $pid = Start-Fallback
+            $bridgePid = Start-Fallback

@@ stop 分支
-            $pid = Read-Pid
-            if (-not $pid) { Write-Host "No bridge running"; exit 0 }
-            if (Test-PidAlive $pid) {
-                Stop-Process -Id ([int]$pid) -Force
+            $bridgePid = Read-Pid
+            if (-not $bridgePid) { Write-Host "No bridge running"; exit 0 }
+            if (Test-PidAlive $bridgePid) {
+                Stop-Process -Id ([int]$bridgePid) -Force

@@ status 分支
-        $pid = Read-Pid
+        $bridgePid = Read-Pid
 ...
-        if ($pid -and (Test-PidAlive $pid)) {
-            Write-Host "Bridge process is running (PID: $pid)"
+        if ($bridgePid -and (Test-PidAlive $bridgePid)) {
+            Write-Host "Bridge process is running (PID: $bridgePid)"

打上以上修复后,在 Windows + PowerShell 7 下 start / stop / status 均恢复正常,桥接可正常拉起、飞书消息收发恢复。

如果需要,我可以把上面的改动整理成 PR。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions