[CmdletBinding()] param( [Parameter(Position = 0)] [string]$ModelPath ) $ErrorActionPreference = 'Stop' $scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path $repoRoot = Split-Path -Parent $scriptDirectory $defaultsFilePath = Join-Path $scriptDirectory 'test-automation.defaults.json' function Resolve-RoamerPath { $candidates = New-Object System.Collections.Generic.List[string] $appPathKeys = @( 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Roamer.exe', 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\App Paths\Roamer.exe' ) foreach ($key in $appPathKeys) { try { $value = (Get-ItemProperty -Path $key -ErrorAction Stop).'(default)' if (-not [string]::IsNullOrWhiteSpace($value)) { $candidates.Add($value) } } catch { } } $wellKnownPaths = @( (Join-Path ${env:ProgramFiles} 'Autodesk\Navisworks Manage 2026\Roamer.exe'), (Join-Path ${env:ProgramFiles(x86)} 'Autodesk\Navisworks Manage 2026\Roamer.exe'), (Join-Path ${env:ProgramFiles} 'Autodesk\Navisworks Simulate 2026\Roamer.exe'), (Join-Path ${env:ProgramFiles(x86)} 'Autodesk\Navisworks Simulate 2026\Roamer.exe') ) | Where-Object { $_ } foreach ($path in $wellKnownPaths) { $candidates.Add($path) } foreach ($candidate in $candidates | Select-Object -Unique) { if (-not [string]::IsNullOrWhiteSpace($candidate) -and (Test-Path $candidate)) { return [System.IO.Path]::GetFullPath($candidate) } } throw '找不到 Roamer.exe。请确认 Navisworks Manage 2026 已安装。' } function Resolve-DefaultModelPath { if (-not (Test-Path $defaultsFilePath)) { return $null } try { $defaults = Get-Content $defaultsFilePath -Raw | ConvertFrom-Json $defaultModelPath = [string]$defaults.defaultModelPath if ([string]::IsNullOrWhiteSpace($defaultModelPath)) { return $null } $resolvedPath = [System.IO.Path]::GetFullPath($defaultModelPath) if (-not (Test-Path $resolvedPath)) { throw "默认模型文件不存在: $resolvedPath" } return $resolvedPath } catch { throw "读取默认测试配置失败: $($_.Exception.Message)" } } function Dismiss-RecoveryPromptIfPresent { param( [int]$TimeoutSeconds = 20 ) Add-Type -AssemblyName System.Windows.Forms | Out-Null $shell = New-Object -ComObject WScript.Shell $windowTitles = @( '是否从自动保存重新载入?', '是否从自动保存重新载入?' ) $deadline = (Get-Date).AddSeconds($TimeoutSeconds) while ((Get-Date) -lt $deadline) { foreach ($windowTitle in $windowTitles) { try { if ($shell.AppActivate($windowTitle)) { Start-Sleep -Milliseconds 300 [System.Windows.Forms.SendKeys]::SendWait('%N') Write-Host '已自动选择“否”以跳过自动保存恢复窗口。' return } } catch { } } Start-Sleep -Milliseconds 500 } } if ([string]::IsNullOrWhiteSpace($ModelPath)) { $ModelPath = Resolve-DefaultModelPath } if (-not [string]::IsNullOrWhiteSpace($ModelPath)) { $ModelPath = [System.IO.Path]::GetFullPath($ModelPath) if (-not (Test-Path $ModelPath)) { throw "模型文件不存在: $ModelPath" } } $roamerPath = Resolve-RoamerPath $existingProcess = Get-Process Roamer -ErrorAction SilentlyContinue | Select-Object -First 1 $env:TRANSPORTPLUGIN_TEST_AUTOMATION = '1' if ($existingProcess) { Write-Host ("Navisworks 已在运行,PID={0}" -f $existingProcess.Id) if (-not [string]::IsNullOrWhiteSpace($ModelPath)) { Start-Process -FilePath $roamerPath -ArgumentList @($ModelPath) | Out-Null Write-Host ("已请求 Navisworks 打开模型: {0}" -f $ModelPath) } Dismiss-RecoveryPromptIfPresent Write-Host '提示: 当前测试 HTTP 服务在插件 DockPane OnLoaded 中启动,首次测试前请确保插件面板已打开。' exit 0 } $arguments = @() if (-not [string]::IsNullOrWhiteSpace($ModelPath)) { $arguments += $ModelPath } $startProcessParams = @{ FilePath = $roamerPath PassThru = $true } if ($arguments.Count -gt 0) { $startProcessParams.ArgumentList = $arguments } $process = Start-Process @startProcessParams Write-Host ("Navisworks 启动中,PID={0}" -f $process.Id) $deadline = (Get-Date).AddSeconds(30) do { Start-Sleep -Milliseconds 500 $running = Get-Process -Id $process.Id -ErrorAction SilentlyContinue } while (-not $running -and (Get-Date) -lt $deadline) if (-not $running) { throw 'Navisworks 启动超时,30 秒内未检测到 Roamer.exe 进程。' } Dismiss-RecoveryPromptIfPresent Write-Host ("Navisworks 已启动: {0}" -f $roamerPath) if (-not [string]::IsNullOrWhiteSpace($ModelPath)) { Write-Host ("已打开模型参数: {0}" -f $ModelPath) } Write-Host '提示: 当前测试 HTTP 服务在插件 DockPane OnLoaded 中启动,首次测试前请确保插件面板已打开。'