Skip to content

[Windows] resident 进程在命令返回后仍阻塞父进程约 60 秒(疑似 #139 未完全修复) #207

Description

@hqy2435662352

maintainer 你们好,

我在 Windows 上使用 officecli 1.0.135 时遇到了一个和 #139 表现相近的问题。#139 已被标记为 completed,但我这边在最新版本上仍能稳定复现,所以新开一个 issue 跟进,烦请确认是否属于同一根因。

现象

通过 PowerShell 非交互式调用 officecli view / get / query 等命令时:

  • 命令本身的 stdout 输出很快就能收到(内容正确)
  • 但 PowerShell 子进程不会立即退出
  • 大约要等 61 秒 后,子进程才退出
  • 设置 OFFICECLI_NO_AUTO_RESIDENT=1 后,问题消失,所有命令都在 1 秒内完成

环境

  • OS: Windows 11
  • Shell: PowerShell 5.1
  • officecli: 1.0.135
  • 安装方式:官方 install.ps1

复现脚本

下面是一个不依赖 OpenCode / AI agent 的独立 PowerShell 脚本。它模拟 agent shell 工具的执行环境:创建一个 stdout 被重定向到管道的子 PowerShell 进程,在里面调用 officecli。

#Requires -Version 5.1
# repro-officecli-139.ps1
param(
    [string]$TestFile = "$env:TEMP\minimal.pptx",
    [int]$TimeoutSeconds = 65
)

function Invoke-OfficeCliViewTest {
    param([string]$Name, [hashtable]$EnvVars = @{})
    Write-Host "`n=========================================="
    Write-Host "TEST: $Name"
    Write-Host "Started at: $(Get-Date -Format 'HH:mm:ss')"

    $inner = ""
    foreach ($k in $EnvVars.Keys) { $inner += "`$env:$k = '$($EnvVars[$k])'; " }
    $inner += "& officecli view '$($TestFile.Replace('\', '\\'))' outline"
    $encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($inner))

    $psi = New-Object System.Diagnostics.ProcessStartInfo
    $psi.FileName = "powershell.exe"
    $psi.Arguments = "-NoLogo -NoProfile -NonInteractive -EncodedCommand $encoded"
    $psi.RedirectStandardOutput = $true
    $psi.RedirectStandardError = $true
    $psi.UseShellExecute = $false
    $psi.CreateNoWindow = $true

    $proc = [System.Diagnostics.Process]::Start($psi)
    $sw = [System.Diagnostics.Stopwatch]::StartNew()
    $completed = $proc.WaitForExit($TimeoutSeconds * 1000)
    $sw.Stop()
    $stdout = $proc.StandardOutput.ReadToEnd()

    if (-not $completed) {
        Write-Host "RESULT: TIMEOUT after $($sw.Elapsed.TotalSeconds.ToString('F1'))s"
        try { $proc.Kill() } catch { }
    } else {
        Write-Host "RESULT: EXITED in $($sw.Elapsed.TotalSeconds.ToString('F1'))s"
    }
    Write-Host "stdout length: $($stdout.Length)"
}

Invoke-OfficeCliViewTest -Name "Default (auto-resident)"
Invoke-OfficeCliViewTest -Name "OFFICECLI_NO_AUTO_RESIDENT=1" -EnvVars @{ OFFICECLI_NO_AUTO_RESIDENT = '1' }

运行方式:

powershell -ExecutionPolicy Bypass -File repro-officecli-139.ps1

验证结果

我用 officecli 自己 create 出来的最小文件做了多组对照,结果如下:

命令 auto-resident OFFICECLI_NO_AUTO_RESIDENT=1
view minimal.pptx outline TIMEOUT 61.5s OK 0.8s
view minimal.xlsx outline TIMEOUT 61.5s OK 1.0s
get minimal.pptx /slide[1] TIMEOUT 61.6s -
get minimal.xlsx /Sheet1/A1 TIMEOUT 61.5s -
query minimal.xlsx cell TIMEOUT 61.5s -

说明:

  1. 不是某个文件格式的问题(PPTX / XLSX 都复现)
  2. 不是某个命令的问题(view / get / query 都复现)
  3. stdout 内容很快就能收到,但子进程要等约 61 秒才退出

我的理解

我推测这可能是 #139 中提到的 resident 进程句柄继承问题在 1.0.135 中仍然存在:resident 进程继承了子 PowerShell 的 stdout/stderr 管道句柄,导致即使命令输出已经返回,管道也无法关闭,父进程只能等到 resident idle timeout(约 60 秒)后才能继续。

如果我的理解有误,还请指正。

Workaround

目前可以通过设置环境变量规避:

$env:OFFICECLI_NO_AUTO_RESIDENT='1'

设置后,上述所有命令都能在 1 秒左右完成。

相关 issue

感谢维护者的时间,期待反馈。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions