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

PowerShell 5.1正常运行的PrintOut代码在7.3中失效问题排查与修复

问题原因分析

PowerShell 5.1基于.NET Framework,在COM互操作时会自动处理字符串到object类型的隐式转换,所以直接传字符串类型的$Pages作为[ref]参数能正常工作。而PowerShell 7.3基于.NET Core/.NET 7,对COM互操作的类型检查更严格,不允许直接将字符串类型的引用传递给期望object类型引用的参数,因此抛出类型转换错误。

修改后的代码

这里提供两种可行的修改方案:

方案一:将$Pages转为object类型

通过显式声明$Pages为object类型,适配PowerShell 7.3的类型要求:

$path = 'D:\SchoolWeb\DOCXtoPDF\test.docx' # 目标docx文件路径

$Word = New-Object -ComObject Word.Application
$Word.Visible = $false
$docx = $Word.Documents.Open($path)

$pagesNum = $Word.ActiveDocument.ComputeStatistics([Microsoft.Office.Interop.Word.WdStatistic]::wdStatisticPages)
$max = $pagesNum - 2 # 排除最后两页

$Missing    = [System.Reflection.Missing]::Value
$BackGround = 0
$Append     = 0
$Range      = 4 # 指定打印自定义页码范围
$OutputFileName = $Missing
$From       = $Missing
$To         = $Missing
$Item       = 0
$Copies     = 1

# 显式将$Pages定义为object类型
[object]$Pages = if ($max -gt 1) { "1-$max" } else { "1" }
    
$Word.PrintOut([ref]$BackGround, [ref]$Append, [ref]$Range, [ref]$OutputFileName, [ref]$From, [ref]$To, [ref]$Item, [ref]$Copies, [ref]$Pages)

$docx.Close($false)
# 清理COM对象,避免Word进程残留
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($docx) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Word) | Out-Null
[GC]::Collect()
[GC]::WaitForPendingFinalizers()

方案二:改用From和To参数指定页码范围(更推荐)

直接使用From和To数值参数定义打印范围,避开字符串格式的Pages参数带来的类型问题,更符合Office互操作规范:

$path = 'D:\SchoolWeb\DOCXtoPDF\test.docx' # 目标docx文件路径

$Word = New-Object -ComObject Word.Application
$Word.Visible = $false
$docx = $Word.Documents.Open($path)

$pagesNum = $Word.ActiveDocument.ComputeStatistics([Microsoft.Office.Interop.Word.WdStatistic]::wdStatisticPages)
$max = $pagesNum - 2 # 排除最后两页

$Missing    = [System.Reflection.Missing]::Value
$BackGround = 0
$Append     = 0
$Range      = 2 # 指定按From和To参数的范围打印
$OutputFileName = $Missing
$From       = 1 # 起始页码
$To         = if ($max -ge 1) { $max } else { 1 } # 结束页码
$Item       = 0
$Copies     = 1
$Pages      = $Missing
    
$Word.PrintOut([ref]$BackGround, [ref]$Append, [ref]$Range, [ref]$OutputFileName, [ref]$From, [ref]$To, [ref]$Item, [ref]$Copies, [ref]$Pages)

$docx.Close($false)
# 清理COM对象,避免Word进程残留
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($docx) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Word) | Out-Null
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
额外说明
  • 方案二的逻辑更清晰,类型匹配更可靠,也避免了字符串解析可能出现的格式问题。
  • 代码中添加了COM对象的清理逻辑,防止PowerShell执行完毕后Word进程在后台残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:31:01