#Requires -Version 5.1 [CmdletBinding()] param( [string]$Solution = $null ) . "$PSScriptRoot\tc-common.ps1" if (-not $Solution) { $Solution = $script:DefaultSolution } New-Log $script:DefaultLogDir $LogFile = Join-Path $script:DefaultLogDir "scan.log" function Write-Log($Message) { $line = "[{0}] {1}" -f (Get-Date -Format 'HH:mm:ss'), $Message Write-Host $line Add-Content -Path $LogFile -Value $line -Encoding UTF8 } Write-Log "=== XAE EtherCAT Scan ===" try { $dte = New-Object -ComObject TcXaeShell.DTE.17.0 -ErrorAction Stop } catch { Write-Log "FATAL: Cannot create DTE: $_" exit 1 } $dte.MainWindow.Visible = $true $dte.Solution.Open($Solution) for ($i = 1; $i -le 120; $i++) { Start-Sleep -Seconds 1 if ($dte.Solution.IsOpen) { break } } Write-Log "Solution open: $($dte.Solution.IsOpen)" $sysMgr = $null for ($i = 1; $i -le 40; $i++) { try { $sysMgr = $dte.Solution.Projects.Item(1).Object if ($sysMgr) { break } } catch {} Start-Sleep -Seconds 3 } if (-not $sysMgr) { Write-Log "FATAL: SysManager is null" exit 1 } Write-Log "SysManager OK" # Set target and platform with retry for RPC_E_CALL_REJECTED $targetNetId = '169.254.176.217.1.1' $platform = 'TwinCAT RT (x64)' for ($i = 1; $i -le 10; $i++) { try { $sysMgr.SetTargetNetId($targetNetId) Write-Log "SetTargetNetId $targetNetId OK (try $i)" break } catch { Write-Log "SetTargetNetId try $i error: $_" Start-Sleep -Seconds 2 } } for ($i = 1; $i -le 10; $i++) { try { $sysMgr.ConfigurationManager.ActiveTargetPlatform = $platform Write-Log "ActiveTargetPlatform set to $platform (try $i)" break } catch { Write-Log "Set platform try $i error: $_" Start-Sleep -Seconds 2 } } Start-Sleep -Seconds 5 try { $cfg = $sysMgr.ConfigurationManager.ActiveConfiguration Write-Log "Active Target NetId: $($cfg.TargetNetId)" Write-Log "Active Platform: $($sysMgr.ConfigurationManager.ActiveTargetPlatform)" } catch { Write-Log "Get active config error: $_" } # Activate configuration Write-Log "Activating configuration..." try { $sysMgr.ActivateConfiguration() Write-Log "ActivateConfiguration OK" } catch { Write-Log "ActivateConfiguration error: $_" } Start-Sleep -Seconds 5 # Restart in config mode $cmdCfgMode = 'TwinCAT.重启TwinCAT配置模式' Write-Log "Restarting TwinCAT in config mode..." try { $dte.ExecuteCommand($cmdCfgMode) Write-Log "ExecuteCommand($cmdCfgMode) OK" } catch { Write-Log "ExecuteCommand($cmdCfgMode) error: $_" } Start-Sleep -Seconds 10 try { Write-Log "IsTwinCATStarted = $($sysMgr.IsTwinCATStarted())" } catch { Write-Log "IsTwinCATStarted error: $_" } # Find EtherCAT device in tree and select it $io = $null for ($i = 1; $i -le 10; $i++) { try { $io = $sysMgr.LookupTreeItem('TIID') if ($io) { break } } catch {} Start-Sleep -Seconds 2 } if (-not $io) { Write-Log "FATAL: Cannot find TIID" exit 1 } $ecat = $null for ($j = 1; $j -le [int]$io.ChildCount; $j++) { try { $ch = $io.Child($j) if ([int]$ch.ItemSubType -eq 111) { $ecat = $ch break } } catch {} } if (-not $ecat) { Write-Log "FATAL: No EtherCAT device found under TIID" exit 1 } Write-Log "EtherCAT device: $($ecat.Name)" # Select in Solution Explorer Write-Log "Selecting EtherCAT device in Solution Explorer..." try { $se = $dte.ToolWindows.SolutionExplorer $se.Parent.Activate() Start-Sleep -Seconds 2 function Find-Node($items) { if ($null -eq $items) { return $null } foreach ($it in $items) { try { if ($it.Name -like '*EtherCAT*') { return $it } } catch {} try { $sub = Find-Node $it.UIHierarchyItems; if ($sub) { return $sub } } catch {} } return $null } $node = Find-Node $se.UIHierarchyItems if ($node) { $node.Select(1) Write-Log "Selected: $($node.Name)" } else { Write-Log "WARN: Could not select EtherCAT node in UI" } } catch { Write-Log "Select node error: $_" } # Trigger scan command $cmdScan = 'TwinCAT.扫描' Write-Log ">>> Invoking $cmdScan -- please confirm scan dialog if it appears <<<" try { $dte.ExecuteCommand($cmdScan) Write-Log "ExecuteCommand($cmdScan) returned" } catch { Write-Log "ExecuteCommand($cmdScan) error: $_" } Write-Log "Scan dialog should be visible. Please confirm it and report what devices were found." Write-Log "Waiting 60s (do not close XAE)..." Start-Sleep -Seconds 60 # Read back after scan $io2 = $sysMgr.LookupTreeItem('TIID') $ecat2 = $null for ($j = 1; $j -le [int]$io2.ChildCount; $j++) { try { $ch = $io2.Child($j) if ([int]$ch.ItemSubType -eq 111) { $ecat2 = $ch; break } } catch {} } if ($ecat2) { Write-Log "Post-scan EtherCAT ChildCount = $($ecat2.ChildCount)" for ($j = 1; $j -le [int]$ecat2.ChildCount; $j++) { try { $b = $ecat2.Child($j) Write-Log " Box[$j]: name='$($b.Name)' subtype=$($b.ItemSubType)" } catch {} } $xml = $ecat2.ProduceXml($false) $xmlFile = Join-Path $script:DefaultLogDir 'scan_ecat.xml' [System.IO.File]::WriteAllText($xmlFile, $xml, [System.Text.Encoding]::UTF8) Write-Log "Post-scan XML saved: $xmlFile" } Write-Log "=== Scan complete ==="