421 lines
22 KiB
PowerShell
421 lines
22 KiB
PowerShell
param([string]$ScriptRootOverride = '')
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
|
||
$scriptRootPath = if ($ScriptRootOverride) { $ScriptRootOverride } else { $PSScriptRoot }
|
||
$root = (Resolve-Path (Join-Path $scriptRootPath '..\..')).Path
|
||
$catalogPath = Join-Path $scriptRootPath 'full-page-catalog.json'
|
||
$screenshots = Join-Path $scriptRootPath 'full-screenshots'
|
||
$docDir = Join-Path $root 'doc'
|
||
$desktop = [Environment]::GetFolderPath('Desktop')
|
||
$sourceDocx = Join-Path $docDir '大连元利流体技术有限公司MES系统操作手册_系统管理篇_样稿.docx'
|
||
$fileName = '大连元利流体技术有限公司MES系统用户操作手册_V1.1_2026-07-23'
|
||
$docxPath = Join-Path $docDir ($fileName + '.docx')
|
||
$pdfPath = Join-Path $docDir ($fileName + '.pdf')
|
||
$desktopDocx = Join-Path $desktop ($fileName + '.docx')
|
||
$desktopPdf = Join-Path $desktop ($fileName + '.pdf')
|
||
$progressPath = Join-Path ([IO.Path]::GetTempPath()) 'mes-full-manual-build.log'
|
||
[IO.File]::WriteAllText($progressPath, "开始生成 $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`r`n", [Text.Encoding]::UTF8)
|
||
|
||
function Write-BuildProgress {
|
||
param([string]$Message)
|
||
[IO.File]::AppendAllText($progressPath, "$(Get-Date -Format 'HH:mm:ss') $Message`r`n", [Text.Encoding]::UTF8)
|
||
}
|
||
|
||
if (-not (Test-Path -LiteralPath $sourceDocx)) { throw "系统管理篇源文档不存在:$sourceDocx" }
|
||
if (-not (Test-Path -LiteralPath $catalogPath)) { throw "页面目录不存在:$catalogPath" }
|
||
|
||
$catalog = Get-Content -Raw -Encoding UTF8 $catalogPath | ConvertFrom-Json
|
||
if ($catalog.Length -ne 69) { throw "页面目录数量应为69,实际为$($catalog.Length)" }
|
||
|
||
foreach ($page in $catalog) {
|
||
$imagePath = Join-Path $screenshots $page.screenshot
|
||
if (-not (Test-Path -LiteralPath $imagePath)) { throw "页面截图不存在:$imagePath" }
|
||
}
|
||
|
||
New-Item -ItemType Directory -Force -Path $docDir | Out-Null
|
||
|
||
$moduleChapters = [ordered]@{
|
||
'设备管理' = 7
|
||
'研发管理' = 8
|
||
'工艺管理' = 9
|
||
'计划排产' = 10
|
||
'生产管理' = 11
|
||
'异常提醒' = 12
|
||
'质量管理' = 13
|
||
'销售订单管理' = 14
|
||
}
|
||
|
||
function Join-Values {
|
||
param([object]$Values, [int]$Limit = 12)
|
||
if ($null -eq $Values -or $Values.Length -eq 0) { return '无' }
|
||
$items = @($Values | Select-Object -First $Limit)
|
||
$text = $items -join '、'
|
||
if ($Values.Length -gt $Limit) { $text += "等$($Values.Length)项" }
|
||
return $text
|
||
}
|
||
|
||
function Get-FilterType {
|
||
param([string]$Field)
|
||
if ($Field -match '日期|时间|开始|结束|完工|入账') { return '日期/时间或范围选择' }
|
||
if ($Field -match '状态|类型|类别|属性|性质|结果|部门|工位|工序|人员|指派|来源|班次|齐套|送检|入库|发货') { return '下拉、开关或选项选择' }
|
||
if ($Field -match '编码|编号|订单|任务ID|计划号|合同号|图号|名称|操作人|物料|产品') { return '文本输入或远程选择' }
|
||
return '输入或选择控件'
|
||
}
|
||
|
||
function Get-FilterGuide {
|
||
param([string]$Field)
|
||
if ($Field -match '日期|时间|开始|结束|完工|入账') { return '选择起止时间时按区间过滤;清空表示不限制该时间条件。' }
|
||
if ($Field -match '状态|类型|类别|属性|性质|结果|部门|工位|工序|人员|指派|来源|班次|齐套|送检|入库|发货') { return '从页面提供的选项中选择;“全部”或清空通常表示不限制该条件。' }
|
||
if ($Field -match '编码|编号|订单|任务ID|计划号|合同号|图号|名称|操作人|物料|产品') { return '输入关键值或从远程候选项中选择,再与其他已填写条件共同查询。' }
|
||
return '按页面控件输入或选择,点击【查询】后与其他条件共同生效。'
|
||
}
|
||
|
||
function Get-ActionGuide {
|
||
param([string]$Button)
|
||
if ($Button -match '查询|搜索|刷新') { return '读取当前筛选条件并刷新列表,不写入业务数据。' }
|
||
if ($Button -match '导出|Excel|下载') { return '将当前查询或当前页签结果导出/下载;导出前先确认筛选范围。' }
|
||
if ($Button -match '查看|预览|明细|记录|图纸|附件') { return '打开当前记录的只读详情、历史、图纸或附件;关闭窗口返回列表。' }
|
||
if ($Button -match '新增|新建|添加|设备$') { return '打开新增窗口,填写必填项并确认后写入;正式操作前检查编码和关联主数据。' }
|
||
if ($Button -match '编辑|修改|修正') { return '选择目标记录后打开编辑窗口,核对影响范围并保存修改。' }
|
||
if ($Button -match '删除|移除|作废|关闭订单') { return '执行不可逆或影响状态的操作;必须核对下游占用并在确认框中再次确认。' }
|
||
if ($Button -match '取消|关闭$|返回') { return '关闭当前窗口或放弃本次未提交内容,通常不写入数据。' }
|
||
if ($Button -match '保存|确定|提交|确认') { return '提交当前表单或选择结果;提交前复核必填项、数量、时间和目标记录。' }
|
||
if ($Button -match '批量|排产|下发|派工|指派') { return '先选择目标行并完整填写工位、人员、数量和时间,再批量生成或下发任务。' }
|
||
if ($Button -match '开始|开工|暂停|结束|完成|报工|送检|收验|收检|发料|收料|领料|退库') { return '改变任务或物料流转状态并形成操作记录;只对已核对的当前任务执行。' }
|
||
if ($Button -match '上传') { return '选择文件并上传到当前业务记录;上传前确认文件版本、格式和归属。' }
|
||
return '按当前选中记录执行对应业务动作;根据弹窗提示核对后再确认。'
|
||
}
|
||
|
||
function Test-WritePage {
|
||
param([object]$Page)
|
||
if ($Page.writeProcedures.Length -gt 0) { return $true }
|
||
return [bool](@($Page.buttons | Where-Object { $_ -match '新增|新建|编辑|修改|删除|保存|确定|提交|开始|结束|完成|报工|送检|收料|发料|排产|下发|上传' }).Length)
|
||
}
|
||
|
||
$word = $null
|
||
$doc = $null
|
||
$buildError = $null
|
||
|
||
try {
|
||
$word = New-Object -ComObject Word.Application
|
||
$word.Visible = $false
|
||
$word.DisplayAlerts = 0
|
||
$doc = $word.Documents.Open($sourceDocx, $false, $false)
|
||
$doc.SaveAs2($docxPath, 16)
|
||
Write-BuildProgress '已打开系统管理篇并另存完整篇'
|
||
$selection = $word.Selection
|
||
$normal = $doc.Styles.Item(-1)
|
||
|
||
function Set-ParagraphText {
|
||
param([object]$Paragraph, [string]$Text)
|
||
$range = $Paragraph.Range.Duplicate
|
||
if ($range.End -gt $range.Start) { $range.End = $range.End - 1 }
|
||
$range.Text = $Text
|
||
}
|
||
|
||
$headingMap = @{
|
||
'7 典型业务链路' = '15 典型业务链路'
|
||
'7.1 新增可登录人员' = '15.1 新增可登录人员'
|
||
'7.2 下线一个角色' = '15.2 下线一个角色'
|
||
'7.3 新增生产工位' = '15.3 新增生产工位'
|
||
'7.4 追溯一次报工操作' = '15.4 追溯一次报工操作'
|
||
'8 常见问题' = '16 常见问题'
|
||
'9 正式环境操作红线' = '17 正式环境操作红线'
|
||
}
|
||
|
||
$paragraphCount = $doc.Paragraphs.Count
|
||
for ($paragraphIndex = 1; $paragraphIndex -le $paragraphCount; $paragraphIndex++) {
|
||
$paragraph = $doc.Paragraphs.Item($paragraphIndex)
|
||
$text = ($paragraph.Range.Text -replace '[\r\a]+$', '').Trim()
|
||
if ($text -eq '系统管理篇(样稿)') {
|
||
Set-ParagraphText $paragraph '完整操作手册(系统管理至销售订单)'
|
||
} elseif ($text -eq '版本:V1.0') {
|
||
Set-ParagraphText $paragraph '版本:V1.1'
|
||
} elseif ($text -eq '编制日期:2026年7月23日') {
|
||
Set-ParagraphText $paragraph '编制日期:2026年7月23日'
|
||
} elseif ($text.StartsWith('当前正式菜单以数据库配置为准,包括人员管理')) {
|
||
Set-ParagraphText $paragraph '当前正式菜单以数据库配置为准。本版在系统管理基础上继续覆盖设备管理、研发管理、工艺管理、计划排产、生产管理、异常提醒、质量管理和销售订单管理,共计74个正式功能页面。'
|
||
} elseif ($headingMap.ContainsKey($text)) {
|
||
Set-ParagraphText $paragraph $headingMap[$text]
|
||
}
|
||
}
|
||
Write-BuildProgress '已更新封面、阅读说明和后续章节编号'
|
||
|
||
$revisionTable = $null
|
||
for ($tableIndex = 1; $tableIndex -le $doc.Tables.Count; $tableIndex++) {
|
||
$candidate = $doc.Tables.Item($tableIndex)
|
||
if ($candidate.Columns.Count -ge 4) {
|
||
$firstCell = ($candidate.Cell(1, 1).Range.Text -replace '[\r\a]+$', '').Trim()
|
||
if ($firstCell -eq '版本') {
|
||
$revisionTable = $candidate
|
||
break
|
||
}
|
||
}
|
||
}
|
||
if ($null -ne $revisionTable) {
|
||
$newRow = $revisionTable.Rows.Add()
|
||
$newRow.Cells.Item(1).Range.Text = 'V1.1'
|
||
$newRow.Cells.Item(2).Range.Text = '2026-07-23'
|
||
$newRow.Cells.Item(3).Range.Text = '增加设备至销售订单八个模块'
|
||
$newRow.Cells.Item(4).Range.Text = '新增69个正式功能页、69张页面截图及完整数据关系说明'
|
||
}
|
||
Write-BuildProgress '已更新修订记录'
|
||
|
||
$insertAt = $null
|
||
$paragraphCount = $doc.Paragraphs.Count
|
||
for ($paragraphIndex = 1; $paragraphIndex -le $paragraphCount; $paragraphIndex++) {
|
||
$paragraph = $doc.Paragraphs.Item($paragraphIndex)
|
||
$text = ($paragraph.Range.Text -replace '[\r\a]+$', '').Trim()
|
||
if ($text -eq '15 典型业务链路') {
|
||
$insertAt = $paragraph.Range.Start
|
||
break
|
||
}
|
||
}
|
||
if ($null -eq $insertAt) { throw '未找到“15 典型业务链路”插入位置' }
|
||
$selection.SetRange($insertAt, $insertAt)
|
||
Write-BuildProgress '已定位模块章节插入位置'
|
||
|
||
function Move-End {
|
||
$selection.SetRange($selection.Range.End, $selection.Range.End)
|
||
}
|
||
|
||
function Add-Text {
|
||
param(
|
||
[string]$Text,
|
||
[double]$Size = 10.5,
|
||
[bool]$Bold = $false,
|
||
[int]$Align = 0,
|
||
[int]$Color = 0,
|
||
[double]$Before = 0,
|
||
[double]$After = 6,
|
||
[double]$FirstIndentCm = 0
|
||
)
|
||
$selection.Font.NameFarEast = '宋体'
|
||
$selection.Font.Name = 'Arial'
|
||
$selection.Font.Size = $Size
|
||
$selection.Font.Bold = [int]$Bold
|
||
$selection.Font.Color = $Color
|
||
$selection.ParagraphFormat.Alignment = $Align
|
||
$selection.ParagraphFormat.SpaceBefore = $Before
|
||
$selection.ParagraphFormat.SpaceAfter = $After
|
||
$selection.ParagraphFormat.FirstLineIndent = $word.CentimetersToPoints($FirstIndentCm)
|
||
$selection.TypeText($Text)
|
||
$selection.TypeParagraph()
|
||
}
|
||
|
||
function Add-Heading {
|
||
param([string]$Text, [int]$Level)
|
||
$styleId = switch ($Level) { 1 { -2 } 2 { -3 } default { -4 } }
|
||
$selection.Style = $doc.Styles.Item($styleId)
|
||
$selection.Font.NameFarEast = '微软雅黑'
|
||
$selection.Font.Name = 'Arial'
|
||
$selection.Font.Color = 0x8F4A31
|
||
$selection.Font.Bold = 1
|
||
$selection.ParagraphFormat.KeepWithNext = -1
|
||
$selection.TypeText($Text)
|
||
$selection.TypeParagraph()
|
||
$selection.Style = $normal
|
||
}
|
||
|
||
function Add-Table {
|
||
param([object[]]$Rows, [double[]]$WidthsCm = @())
|
||
if ($Rows.Count -eq 0) { return }
|
||
$range = $selection.Range
|
||
$table = $doc.Tables.Add($range, $Rows.Count, $Rows[0].Count)
|
||
$table.Borders.Enable = 1
|
||
$table.Range.Font.NameFarEast = '宋体'
|
||
$table.Range.Font.Name = 'Arial'
|
||
$table.Range.Font.Size = 8.5
|
||
$table.Range.ParagraphFormat.SpaceAfter = 0
|
||
for ($r = 0; $r -lt $Rows.Count; $r++) {
|
||
for ($c = 0; $c -lt $Rows[$r].Count; $c++) {
|
||
$table.Cell($r + 1, $c + 1).Range.Text = [string]$Rows[$r][$c]
|
||
$table.Cell($r + 1, $c + 1).VerticalAlignment = 1
|
||
if ($WidthsCm.Count -gt $c) {
|
||
$table.Cell($r + 1, $c + 1).Width = $word.CentimetersToPoints($WidthsCm[$c])
|
||
}
|
||
}
|
||
}
|
||
$table.Rows.Item(1).Range.Bold = 1
|
||
$table.Rows.Item(1).Shading.BackgroundPatternColor = 0xE6D8D0
|
||
$table.Rows.Item(1).Range.ParagraphFormat.Alignment = 1
|
||
$table.AllowAutoFit = -1
|
||
$selection.SetRange($table.Range.End, $table.Range.End)
|
||
$selection.TypeParagraph()
|
||
}
|
||
|
||
function Add-Note {
|
||
param([string]$Title, [string]$Text, [string]$Kind = 'info')
|
||
$range = $selection.Range
|
||
$table = $doc.Tables.Add($range, 1, 1)
|
||
$table.Borders.Enable = 1
|
||
$cell = $table.Cell(1, 1)
|
||
$cell.Range.Text = $Title + ':' + $Text
|
||
$cell.Range.Font.NameFarEast = '微软雅黑'
|
||
$cell.Range.Font.Name = 'Arial'
|
||
$cell.Range.Font.Size = 9.5
|
||
$cell.Range.ParagraphFormat.SpaceAfter = 0
|
||
if ($Kind -eq 'warn') { $cell.Shading.BackgroundPatternColor = 0xD9F2FF }
|
||
elseif ($Kind -eq 'danger') { $cell.Shading.BackgroundPatternColor = 0xD9E2F3 }
|
||
else { $cell.Shading.BackgroundPatternColor = 0xF4F1EE }
|
||
$selection.SetRange($table.Range.End, $table.Range.End)
|
||
$selection.TypeParagraph()
|
||
}
|
||
|
||
function Add-Figure {
|
||
param([string]$Path, [string]$Caption, [double]$MaxWidthCm = 16.4)
|
||
$selection.ParagraphFormat.Alignment = 1
|
||
$shape = $selection.InlineShapes.AddPicture($Path, $false, $true, $selection.Range)
|
||
$shape.LockAspectRatio = -1
|
||
$maxWidth = $word.CentimetersToPoints($MaxWidthCm)
|
||
if ($shape.Width -gt $maxWidth) { $shape.Width = $maxWidth }
|
||
$selection.SetRange($shape.Range.End, $shape.Range.End)
|
||
$selection.TypeParagraph()
|
||
Add-Text $Caption 9 $false 1 0x777777 0 8 0
|
||
}
|
||
|
||
function Add-PageBreak {
|
||
$selection.InsertBreak(7)
|
||
}
|
||
|
||
Add-PageBreak
|
||
foreach ($moduleName in $moduleChapters.Keys) {
|
||
$chapter = $moduleChapters[$moduleName]
|
||
$modulePages = @($catalog | Where-Object { $_.module -eq $moduleName } | Sort-Object pageIndex)
|
||
if ($modulePages.Count -eq 0) { continue }
|
||
Write-BuildProgress "开始生成第$chapter章 $moduleName"
|
||
|
||
Add-Heading ("$chapter $moduleName") 1
|
||
Add-Text $modulePages[0].moduleRelation 10.5 $false 0 0 0 6 0.74
|
||
Add-Note '本章范围' "本章按正式菜单顺序说明$($modulePages.Count)个功能页。截图仅执行登录、页面导航和默认查询,没有点击任何业务写入按钮。" 'warn'
|
||
|
||
$moduleRows = [System.Collections.Generic.List[object]]::new()
|
||
$moduleRows.Add(@('序号', '功能页面', '主要用途'))
|
||
for ($i = 0; $i -lt $modulePages.Count; $i++) {
|
||
$moduleRows.Add(@(($i + 1).ToString(), $modulePages[$i].title, $modulePages[$i].purpose))
|
||
}
|
||
Add-Table $moduleRows.ToArray() @(1.2, 3.4, 10.8)
|
||
|
||
for ($pageIndex = 0; $pageIndex -lt $modulePages.Count; $pageIndex++) {
|
||
$page = $modulePages[$pageIndex]
|
||
$section = "$chapter.$($pageIndex + 1)"
|
||
Write-BuildProgress "生成 $section $($page.title)"
|
||
Add-PageBreak
|
||
Add-Heading ("$section $($page.title)") 2
|
||
Add-Text $page.purpose 10.5 $false 0 0 0 6 0.74
|
||
|
||
$writePage = Test-WritePage $page
|
||
Add-Table @(
|
||
@('项目', '说明'),
|
||
@('菜单路径', "$moduleName > $($page.title)"),
|
||
@('页面路由', $page.route),
|
||
@('数据性质', $(if ($writePage) { '查询为只读;业务按钮可能新增、修改或改变状态' } else { '以只读查询、汇总或导出为主' }))
|
||
) @(3.2, 12.2)
|
||
|
||
Add-Figure (Join-Path $screenshots $page.screenshot) ("图 $section-1 $moduleName - $($page.title)正式页面")
|
||
|
||
Add-Heading ("$section.1 搜索与过滤") 3
|
||
if ($page.searchFields.Length -gt 0) {
|
||
$filterRows = [System.Collections.Generic.List[object]]::new()
|
||
$filterRows.Add(@('条件', '控件形式', '使用说明'))
|
||
foreach ($field in $page.searchFields) {
|
||
$filterRows.Add(@($field, (Get-FilterType $field), (Get-FilterGuide $field)))
|
||
}
|
||
Add-Table $filterRows.ToArray() @(3.2, 4.2, 8.2)
|
||
Add-Note '组合规则' '多个条件同时填写时,由页面一并传入后台查询,通常取条件交集。若查询不到记录,先逐项清空状态、日期和编号条件,再重新查询;精确或包含匹配以对应页面后台过程为准。' 'info'
|
||
} else {
|
||
Add-Text '本页面没有独立的顶部搜索区,进入页面后按默认条件加载数据,或通过页签、树节点、当前工位/人员上下文切换数据范围。' 10.5 $false 0 0 0 6 0.74
|
||
}
|
||
if ($page.tabs.Length -gt 0) {
|
||
Add-Table @(
|
||
@('页面页签/视图', '切换说明'),
|
||
@((Join-Values $page.tabs 20), '切换页签会改变展示维度或数据范围;导出前确认当前页签。')
|
||
) @(5.2, 10.4)
|
||
}
|
||
|
||
Add-Heading ("$section.2 列表字段与页面结果") 3
|
||
if ($page.tableColumns.Length -gt 0) {
|
||
$columnRows = [System.Collections.Generic.List[object]]::new()
|
||
$columnRows.Add(@('分组', '字段/列'))
|
||
for ($columnIndex = 0; $columnIndex -lt $page.tableColumns.Length; $columnIndex += 8) {
|
||
$endIndex = [Math]::Min($columnIndex + 7, $page.tableColumns.Length - 1)
|
||
$group = @($page.tableColumns[$columnIndex..$endIndex])
|
||
$columnRows.Add(@("第$($columnIndex + 1)-$($endIndex + 1)列", ($group -join '、')))
|
||
}
|
||
Add-Table $columnRows.ToArray() @(3.2, 12.4)
|
||
Add-Text '列表用于展示当前筛选结果。存在横向滚动条时,应左右滚动核对全部状态、数量、时间和操作列;存在分页时,页码和每页条数只影响当前显示范围。' 10.5 $false 0 0 0 6 0.74
|
||
} else {
|
||
Add-Text '该页面主要使用自定义看板、卡片或复用组件展示结果,字段布局以截图及页面实时内容为准。' 10.5 $false 0 0 0 6 0.74
|
||
}
|
||
|
||
Add-Heading ("$section.3 功能按钮与操作") 3
|
||
if ($page.buttons.Length -gt 0) {
|
||
$buttonRows = [System.Collections.Generic.List[object]]::new()
|
||
$buttonRows.Add(@('按钮/命令', '操作说明'))
|
||
foreach ($button in $page.buttons) {
|
||
$buttonRows.Add(@($button, (Get-ActionGuide $button)))
|
||
}
|
||
Add-Table $buttonRows.ToArray() @(4.2, 11.4)
|
||
} else {
|
||
Add-Text '本页主要通过大尺寸现场操作按钮、图标按钮、表格行操作或复用组件执行命令。操作前必须先选择当前任务,并根据按钮文字和确认提示核对目标记录。' 10.5 $false 0 0 0 6 0.74
|
||
}
|
||
if ($writePage) {
|
||
Add-Note '正式操作注意' '新增、编辑、删除、开始、结束、排产、报工、送检、收料、上传等操作会写入业务数据或改变状态。本文档编制未实际执行这些按钮;正式使用时应按岗位权限和业务单据逐条确认。' 'danger'
|
||
}
|
||
|
||
Add-Heading ("$section.4 前后数据关系") 3
|
||
Add-Text $page.moduleRelation 10.5 $false 0 0 0 6 0.74
|
||
Add-Table @(
|
||
@('关系层次', '内容'),
|
||
@('页面输入', $(if ($page.searchFields.Length -gt 0) { Join-Values $page.searchFields 18 } else { '当前登录人员、角色、工位、默认状态或上游任务上下文' })),
|
||
@('只读查询过程/接口', (Join-Values $page.readProcedures 10)),
|
||
@('写入过程/接口', (Join-Values $page.writeProcedures 10)),
|
||
@('页面输出', $(if ($page.tableColumns.Length -gt 0) { Join-Values $page.tableColumns 16 } else { '自定义看板、统计结果、状态卡片或复用组件结果' }))
|
||
) @(4.2, 11.4)
|
||
Add-Note '技术核对说明' '过程名称来自当前前端源码和已引用接口文件,用于说明数据流向;动态过程名、通用审批接口及服务端二次调用可能不会全部显示在本表中。' 'info'
|
||
}
|
||
Write-BuildProgress "完成第$chapter章 $moduleName"
|
||
}
|
||
|
||
Write-BuildProgress '开始更新目录并导出PDF'
|
||
if ($doc.TablesOfContents.Count -gt 0) {
|
||
$doc.TablesOfContents.Item(1).Update()
|
||
}
|
||
$doc.Save()
|
||
Write-BuildProgress 'DOCX正文及目录已保存'
|
||
$doc.ExportAsFixedFormat($pdfPath, 17)
|
||
Write-BuildProgress 'PDF已导出'
|
||
|
||
# WPS 兼容层在大型文档导出后读取统计信息可能长时间阻塞,统计校验改由生成后的 Open XML/PDF 文件完成。
|
||
$doc.Close($false)
|
||
[void][Runtime.InteropServices.Marshal]::ReleaseComObject($doc)
|
||
$doc = $null
|
||
$word.Quit()
|
||
[void][Runtime.InteropServices.Marshal]::ReleaseComObject($word)
|
||
$word = $null
|
||
|
||
Copy-Item -LiteralPath $docxPath -Destination $desktopDocx -Force
|
||
Copy-Item -LiteralPath $pdfPath -Destination $desktopPdf -Force
|
||
|
||
Write-Output "DOCX=$docxPath"
|
||
Write-Output "PDF=$pdfPath"
|
||
Write-BuildProgress '完整操作手册生成完成'
|
||
} catch {
|
||
$buildError = $_
|
||
Write-BuildProgress ("生成失败:" + $_.Exception.Message)
|
||
} finally {
|
||
if ($doc) {
|
||
try { $doc.Close($false) } catch { }
|
||
}
|
||
if ($word) {
|
||
try { $word.Quit() } catch { }
|
||
}
|
||
if ($doc) { [void][Runtime.InteropServices.Marshal]::ReleaseComObject($doc) }
|
||
if ($word) { [void][Runtime.InteropServices.Marshal]::ReleaseComObject($word) }
|
||
[GC]::Collect()
|
||
[GC]::WaitForPendingFinalizers()
|
||
}
|
||
|
||
if ($buildError) { throw $buildError }
|