You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab流水线中PowerShell脚本转Docx为PDF时执行异常求助

Docx转PDF脚本在GitLab流水线执行失败问题

我编写了一段PowerShell脚本,手动执行可正常将Docx文件转换为PDF,但在GitLab流水线中调用时出现异常,脚本无法正常结束,Word进程还会持续占用内存,只能手动终止。

脚本内容

param(
    [string]$File,  # Path to document
    [string]$DestinationFolder,  # Path of folder
    [string]$NewName   # New name for converted file
)

# ======== check if parameter are valid ========
if (-not $File) {
    Write-Error "Parameter '-File' must not be empty"
    exit 1
}

if (-not $DestinationFolder) {
    $DestinationFolder = Split-Path -Path $File
}

if (-not $NewName) {
    $NewName = [System.IO.Path]::GetFileNameWithoutExtension($File) + ".pdf"
}

# ======== create destination folder if not exists ========
if (-not (Test-Path -Path $DestinationFolder)) {
    $null = New-Item -Path $DestinationFolder -ItemType Directory -Force
    Write-Output "Path did not exist. Created folder: $DestinationFolder"
}

# ======== export pdf ========
Write-Output "Export pdf"
$Word = New-Object -ComObject 'Word.Application'
$Document = $Word.Documents.Open($File)
$NewFilePath = [string](Join-Path $DestinationFolder $NewName)
$Document.SaveAs($NewFilePath, 17)
$Document.Close()
$Word.Quit()
Write-Output "Stored to $NewFilePath"

报错信息

At D:\GitLab-Runner\builds\yxFfC2Egu\0\SPS_Entwicklung\test\ci-dev-test\ci\release\docx_to_pdf.ps1
:44 char:5
+     $Document.SaveAs($NewFilePath, 17)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
At D:\GitLab-Runner\builds\yxFfC2Egu\0\SPS_Entwicklung\test\ci-dev-test\ci\release\docx_to_pdf.ps1
:45 char:5
+     $Document.Close()
+     ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

已排查情况

  • GitLab Runner服务以管理员用户启动
  • 使用该管理员用户手动执行脚本可正常运行
  • 尝试用Python实现同类功能时,出现类似ValueError('NULL COM pointer access',)错误,参考相关方案后未解决

解决办法

1. 给GitLab Runner服务开启桌面交互权限

Windows服务默认没有桌面会话,而Office COM组件依赖桌面环境才能正常工作:

  • 打开「服务」管理器,找到GitLab Runner服务
  • 右键选择「属性」,切换到「登录」选项卡
  • 勾选「允许服务与桌面交互」,点击确定后重启服务

2. 修改脚本,增加异常处理与COM对象释放

原脚本未处理异常,且未正确释放COM对象,容易导致进程残留。修改后的导出部分代码如下:

# ======== export pdf ========
Write-Output "Export pdf"
$Word = $null
$Document = $null
try {
    $Word = New-Object -ComObject 'Word.Application'
    $Word.Visible = $false
    $Word.DisplayAlerts = 0  # 禁用所有Office提示弹窗,避免阻塞
    $Document = $Word.Documents.Open($File)
    $NewFilePath = [string](Join-Path $DestinationFolder $NewName)
    $Document.SaveAs($NewFilePath, 17)
    Write-Output "Stored to $NewFilePath"
}
catch {
    Write-Error "转换失败: $_"
    exit 1
}
finally {
    # 强制释放文档对象
    if ($Document) {
        $Document.Close()
        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Document) | Out-Null
    }
    # 强制退出Word并释放对象
    if ($Word) {
        $Word.Quit()
        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Word) | Out-Null
        [System.GC]::Collect()
        [System.GC]::WaitForPendingFinalizers()
    }
}

原因说明

GitLab Runner作为Windows服务运行时,默认处于无桌面的会话环境,Microsoft Office的COM组件(如Word)需要桌面交互才能正确初始化文档对象,这就是为什么手动执行正常,但流水线中$Document会返回null的核心原因。同时,原脚本未处理异常和释放COM对象,导致Word进程无法正常退出,持续占用内存。

内容的提问来源于stack exchange,提问作者Pukinn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:54:57