param([Parameter(Mandatory=$true)][string]$OutFile, [Parameter(Mandatory=$true)][string]$Work) $lines = New-Object System.Collections.Generic.List[string] function L($s) { $lines.Add($s); [System.IO.File]::WriteAllLines($OutFile, $lines, (New-Object System.Text.UTF8Encoding($false))) } L ("PSVersion: " + $PSVersionTable.PSVersion + " IsOutputRedirected=" + [Console]::IsOutputRedirected) $nstack = Join-Path $Work 'nstack111\lib\netstandard2.0\NStack.dll' $tg = Join-Path $Work 'tg115\lib\net472\Terminal.Gui.dll' $sc = Join-Path $Work 'sc049\lib\netstandard2.0\Spectre.Console.dll' function Dump($asm, $tag) { L (" [" + $tag + "] FullName = " + $asm.FullName) try { L (" [$tag] Location = " + $asm.Location) } catch { L (" [$tag] Location: dynamic") } try { $ts = $asm.GetTypes() L (" [$tag] GetTypes() = " + $ts.Count + " types") $pub = $ts | Where-Object { $_.IsPublic } | Select-Object -First 4 L (" [$tag] sample public: " + (($pub | ForEach-Object { $_.FullName }) -join ' | ')) $app = $ts | Where-Object { $_.FullName -eq 'Terminal.Gui.Application' } L (" [$tag] type named Terminal.Gui.Application in GetTypes(): " + $(if ($app) { 'YES -> ' + $app.AssemblyQualifiedName } else { 'NO' })) } catch { L (" [$tag] GetTypes() THREW: " + $_.Exception.Message) } } L "" L "=== STEP 1: Add-Type -Path (no prior load) ===" Add-Type -Path $nstack L " NStack Add-Type OK" Add-Type -Path $tg L " Terminal.Gui Add-Type OK" $loaded = [AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GetName().Name -in @('NStack','Terminal.Gui') } foreach ($a in $loaded) { Dump $a $a.GetName().Name } L "" L "=== STEP 2: type resolution methods ===" $tgAsm = $loaded | Where-Object { $_.GetName().Name -eq 'Terminal.Gui' } L (" asm.GetType('Terminal.Gui.Application') -> " + $(try { $r = $tgAsm.GetType('Terminal.Gui.Application'); if ($r) { 'FOUND ' + $r.FullName } else { 'null' } } catch { 'THREW ' + $_.Exception.Message })) L (" [Type]::GetType('Terminal.Gui.Application, Terminal.Gui') -> " + $(try { $r = [Type]::GetType('Terminal.Gui.Application, Terminal.Gui'); if ($r) { 'FOUND ' + $r.FullName } else { 'null' } } catch { 'THREW ' + $_.Exception.Message })) try { $aq = $tgAsm.GetName().FullName L (" asm fullname = " + $aq) $r2 = [Type]::GetType('Terminal.Gui.Application, ' + $aq) L (" [Type]::GetType(full qualified) -> " + $(if ($r2) { 'FOUND' } else { 'null' })) } catch { L (" full-qualified Type.GetType THREW: " + $_.Exception.Message) } L "" L "=== STEP 3: Application static method overloads (real API) ===" $appType = $tgAsm.GetType('Terminal.Gui.Application') if ($appType) { foreach ($m in ($appType.GetMethods([System.Reflection.BindingFlags]'Public,Static') | Where-Object { $_.Name -in @('Init','Shutdown','Run','Refresh','Begin','End') })) { L (" " + $m.ReturnType.Name + " " + $m.Name + "(" + (($m.GetParameters() | ForEach-Object { $_.ParameterType.Name + ' ' + $_.Name }) -join ', ') + ")") } } L "" L "=== STEP 4: Spectre.Console type resolution ===" Add-Type -Path $sc L " Spectre.Console Add-Type OK" $scAsm = [AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GetName().Name -eq 'Spectre.Console' } Dump $scAsm 'Spectre.Console' $ansiT = $scAsm.GetType('Spectre.Console.AnsiConsole') L (" scAsm.GetType('Spectre.Console.AnsiConsole') -> " + $(if ($ansiT) { 'FOUND' } else { 'null' })) if ($ansiT) { L (" static methods of AnsiConsole: " + (($ansiT.GetMethods([System.Reflection.BindingFlags]'Public,Static') | Select-Object -First 25 | ForEach-Object { $_.Name }) -join ', ')) } L "" L "=== STEP 5: is Table.AddRow an EXTENSION method on IGridColumn/Table? ===" $tableT = $scAsm.GetType('Spectre.Console.Table') L (" Table type: " + [bool]$tableT) if ($tableT) { L (" Table instance methods containing 'Add': " + (($tableT.GetMethods() | Where-Object { $_.Name -like '*Add*' } | ForEach-Object { $_.Name + '(' + (($_.GetParameters() | ForEach-Object { $_.ParameterType.Name }) -join ',') + ')' }) -join ' | ')) L (" Table properties: " + (($tableT.GetProperties() | ForEach-Object { $_.PropertyType.Name + ' ' + $_.Name }) -join ', ')) } $extT = $scAsm.GetType('Spectre.Console.TableExtensions') L (" TableExtensions type: " + [bool]$extT) if ($extT) { $em = $extT.GetMethods([System.Reflection.BindingFlags]'Public,Static') | Where-Object { $_.Name -like '*Row*' -or $_.Name -like '*Column*' } foreach ($m in $em) { L (" ext: " + $m.ReturnType.Name + ' ' + $m.Name + '(' + (($m.GetParameters() | ForEach-Object { $_.ParameterType.Name + ' ' + $_.Name }) -join ', ') + ')') } } L "" L "=== STEP 6: Spectre prompts / progress classes available in netstandard2.0 build ===" foreach ($n in @('Spectre.Console.ConfirmationPrompt','Spectre.Console.SelectionPrompt`1','Spectre.Console.MultiSelectionPrompt`1','Spectre.Console.TextPrompt`1','Spectre.Console.Progress','Spectre.Console.Status','Spectre.Console.Live','Spectre.Console.Layout','Spectre.Console.Panel','Spectre.Console.Rule','Spectre.Console.Tree','Spectre.Console.BarChart','Spectre.Console.BreakdownChart','Spectre.Console.ProgressBar','Spectre.Console.ProgressColumn','Spectre.Console.SpinnerColumn','Spectre.Console.Columns','Spectre.Console.Rows','Spectre.Console.Grid','Spectre.Console.Padder','Spectre.Console.Align','Spectre.Console.Canvas','Spectre.Console.Json','Spectre.Console.Calendar','Spectre.Console.ExceptionFormats','Spectre.Console.AnsiConsoleSettings','Spectre.Console.AnsiConsoleFactory','Spectre.Console.IAnsiConsole')) { $tt = $scAsm.GetType($n) L (" " + $n.PadRight(44) + " -> " + $(if ($tt) { 'AVAILABLE' } else { 'MISSING' })) }