none
Escape codes not working inside PowerShell form RRS feed

  • Question

  • Hi, I need some help, please. If you run this PowerShell code, you will see three lines of text displayed in different colours.

    Clear-Host
    $ESC = [char]27
    
    "$ESC[38;2;102;255;255m$('Can you see this?')$ESC[0m"
    
    Function DisplayEscapeCodes
    {
    	"$ESC[38;2;153;51;255m$('What about this?')$ESC[0m"
    	"$ESC[38;2;204;0;204m$('And this?')$ESC[0m"
    }
    
    DisplayEscapeCodes

    I'm having a problem when trying to display coloured text using escape codes inside a PowerShell form. If you run the code below, the only text that will be displayed is "Can you see this?"

    Clear-Host
    $ESC = [char]27
    
    "$ESC[38;2;102;255;255m$('Can you see this?')$ESC[0m"
    
    Function EndForm
    {
    	$OKButton.Dispose();
    	$Form.Dispose();
    	$Form.Close()
    }
    
    Function DisplayEscapeCodes
    {
    	EndForm
    	"$ESC[38;2;153;51;255m$('What about this?')$ESC[0m"
    	"$ESC[38;2;204;0;204m$('And this?')$ESC[0m"
    }
    
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "Test"
    $Form.Font = New-Object System.Drawing.Font('Segoe UI Light',14,[System.Drawing.FontStyle]::Regular)
    $Form.Size = New-Object System.Drawing.Size(400,400) 
    $Form.MinimizeBox = $False
    $Form.MaximizeBox = $False
    $Form.ControlBox = $False
    $Form.ShowIcon = $False
    $Form.BackColor = "White"
    $Form.ForeColor = "Black"
    $Form.WindowState = "Normal"
    $Form.FormBorderStyle = "Fixed3D"
    $Form.ShowInTaskbar = $False
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True
    
    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Size(150,200)
    $OKButton.Size = New-Object System.Drawing.Size(80,40)
    $OKButton.Text = "OK"
    $OKButton.Add_Click({DisplayEscapeCodes})
    
    $Form.Controls.Add($OKButton)
    $Form.ShowDialog() | Out-Null
    

    Is this a bug, or am I doing something wrong? I need to use escape codes because they provide far more than the standard 16 PowerShell colours.

    On another forum, I was advised to change the following:

    $OKButton.Add_Click({DisplayEscapeCodes}) #Original
    $OKButton.Add_Click({Write-Host (DisplayEscapeCodes)}) #Suggested change
    

    While this did display the additional text (and in the correct colours), they were both on the same line, i.e. no carriage return and I need them to be on separate lines.

    Thanks in advance for your help.

    Tuesday, March 17, 2020 3:56 AM

Answers

  • This will output colorized text to the console using escape codes.

    Add-Type -AssemblyName System.Windows.Forms
    $esc = [char]27
    
    $form = [System.Windows.Forms.Form]::new()
    $form.Text = 'Test'
    $form.Size = '400,400'
    $form.FormBorderStyle = 'FixedToolWindow'
    $form.StartPosition = 'CenterScreen'
    $form.Topmost = $true
    
    $button = [System.Windows.Forms.Button]::new()
    $form.Controls.Add($button)
    $button.Text = 'Click Me!'
    $button.Dock = 'Fill'
    
    $button.Add_Click({
        Write-Host "$esc[38;2;102;255;255m$('Can you see this?')$esc[0m"
        Write-Host "$esc[38;2;153;51;255m$('What about this?')$esc[0m"
        Write-Host "$esc[38;2;204;0;204m$('And this?')$esc[0m"
    })
    
    $form.ShowDialog()
    
    


    \_(ツ)_/

    • Marked as answer by Jayson Gabler Wednesday, March 18, 2020 2:03 AM
    Wednesday, March 18, 2020 12:01 AM

All replies

  • If there's an alternative to using escape codes that allows me to access the full spectrum of RGB colours, I'm open to using it.
    Tuesday, March 17, 2020 4:03 AM
  • PowerShell does not support ANSI.  Windows does not support ANSI.  To use ANSI codes you will have to install an ANSI terminal emulator of some kind.

    Windows Forms support the entire range of RGB codes.

    [System.Drawing.Color]|gm -static

    [System.Drawing.Color]::FromArgb([byte]$red,[byte]$green,[byte]$blue)


    \_(ツ)_/

    Tuesday, March 17, 2020 5:23 AM
  • Thanks, I'll give that a try.
    Tuesday, March 17, 2020 5:32 AM
  • This will get you all of the colors:

    $colorPicker = [System.Windows.Forms.ColorDialog]::new()
    $colorPicker.FullOpen =  $true
    $colorPicker.ShowDialog()


    \_(ツ)_/

    Tuesday, March 17, 2020 5:49 AM
  • To display colored text in controls you need to set the foreground color you want.  A control can have only one color at a time.

    If you need to display multiple colors in a control you will need to write a custom "Paint" event handler.

    You an use teh RichTextBox Control to display colors and lines using RTF or manually by programming teh output to the control to set the color for each line, character or group of characters.


    \_(ツ)_/

    Tuesday, March 17, 2020 6:07 AM
  • Here is a quick demo.

    Add-Type -AssemblyName System.Windows.Forms
    
    $form = [System.Windows.Forms.Form]::new()
    $form.Text = 'Test'
    $form.Size = '400,400'
    $form.FormBorderStyle = 'FixedToolWindow'
    $form.StartPosition = 'CenterScreen'
    $form.Topmost = $true
    
    $richtextbox1 = [System.Windows.Forms.RichTextBox]::new()
    $form.Controls.Add($richtextbox1)
    $richtextbox1.Dock = 'Fill'
    
    $form.add_Load({
        $richtextbox1.BackColor = 'LightGray'
        [System.Drawing.Color] | 
            Get-Member -MemberType Property -Static | 
            select Name -Expand Name |
            Where-Object{$_ -ne 'Empty' } |
            ForEach-Object{
                $richtextbox1.SelectionColor = 'Black'
                $richtextbox1.AppendText('This line is ')
                $richtextbox1.SelectionColor = $_
                $richtextbox1.AppendText("$_`n")
            }
        $richtextbox1.Select(0,0)
        $richtextbox1.ScrollToCaret()
    })
    
    $form.ShowDialog()
    
    


    \_(ツ)_/

    Tuesday, March 17, 2020 6:26 AM
  • Hi, I think I should clarify that the text output will be viewed in the PowerShell console, the form is just a front end to give the user options on what servers he can view.

    So is this able to be adapted to the Write-Host command (or something similar)?

    Tuesday, March 17, 2020 11:48 PM
  • Then you are limited to only the colors available with the escape code supported by Windows 10 console and only if VT mode is enabled.

    You cannot send output from a form to the console with "Write-Output".  Only "Write-Host" will display on the console.


    \_(ツ)_/

    Tuesday, March 17, 2020 11:55 PM
  • This will output colorized text to the console using escape codes.

    Add-Type -AssemblyName System.Windows.Forms
    $esc = [char]27
    
    $form = [System.Windows.Forms.Form]::new()
    $form.Text = 'Test'
    $form.Size = '400,400'
    $form.FormBorderStyle = 'FixedToolWindow'
    $form.StartPosition = 'CenterScreen'
    $form.Topmost = $true
    
    $button = [System.Windows.Forms.Button]::new()
    $form.Controls.Add($button)
    $button.Text = 'Click Me!'
    $button.Dock = 'Fill'
    
    $button.Add_Click({
        Write-Host "$esc[38;2;102;255;255m$('Can you see this?')$esc[0m"
        Write-Host "$esc[38;2;153;51;255m$('What about this?')$esc[0m"
        Write-Host "$esc[38;2;204;0;204m$('And this?')$esc[0m"
    })
    
    $form.ShowDialog()
    
    


    \_(ツ)_/

    • Marked as answer by Jayson Gabler Wednesday, March 18, 2020 2:03 AM
    Wednesday, March 18, 2020 12:01 AM
  • Oh right, so it's a simple as preceding the escape codes with "Write-Host"? Cool, thanks mate. I'll let you know if it worked and mark it as the answer.

    Thanks so much for your help!

    Wednesday, March 18, 2020 2:00 AM
  • Yep, that worked! Thanks again.
    Wednesday, March 18, 2020 2:03 AM
  • Is there a way I can "upvote" you?
    Wednesday, March 18, 2020 2:05 AM
  • Add-Type -AssemblyName System.Windows.Forms
    
    function Write-Ansi{
        param(
            $Text = 'No Message',
            $Color = 'Black'
        )
        $rgb = [system.drawing.color]::FromKnownColor($Color)
        $line = '{0}[38;2;{1};{2};{3}m{4}{0}[0m' -f [char]27,$rgb.R,$rgb.G,$rgb.B,$Text
        write-Host $line
    }
    
    $form = [System.Windows.Forms.Form]::new()
    $form.Text = 'Test'
    $form.Size = '400,400'
    $form.FormBorderStyle = 'FixedToolWindow'
    $form.StartPosition = 'CenterScreen'
    $form.Topmost = $true
    
    $button = [System.Windows.Forms.Button]::new()
    $form.Controls.Add($button)
    $button.Text = 'Click Me!'
    $button.Dock = 'Fill'
    $button.add_Click({
        Write-Ansi 'hello world'
        Write-Ansi 'hello world' green
        Write-Ansi 'hello world' lightgreen
        Write-Ansi 'hello world' cyan
    })
    
    $form.ShowDialog()
    


    \_(ツ)_/

    Wednesday, March 18, 2020 2:21 AM
  • This will allow using RGB codes and INTs to define the colors.

    Add-Type -AssemblyName System.Windows.Forms
    
    function Write-Ansi{
        param(
            [Parameter(Mandatory)]
            $Text,
            $Color,
            [int]$RGBA
        )
        if($RGBA){
            $rgb = [system.drawing.color]$RGBA
        }elseif($Color){
            $rgb = [system.drawing.color]::FromKnownColor($Color)
        }else{
            $rgb = [system.drawing.color]::White
        }
        $line = '{0}[38;2;{1};{2};{3}m{4}{0}[0m' -f [char]27,$rgb.R,$rgb.G,$rgb.B,$Text
        write-Host $line
    }
    
    $form = [System.Windows.Forms.Form]::new()
    $form.Text = 'Test'
    $form.Size = '400,400'
    $form.FormBorderStyle = 'FixedToolWindow'
    $form.StartPosition = 'CenterScreen'
    $form.Topmost = $true
    
    $button = [System.Windows.Forms.Button]::new()
    $form.Controls.Add($button)
    $button.Text = 'Click Me!'
    $button.Dock = 'Fill'
    $button.add_Click({
        Write-Ansi 'hello world'
        Write-Ansi 'hello world' green
        Write-Ansi 'hello world' lightgreen
        Write-Ansi 'hello world' cyan
        Write-Ansi 'hello world' -RGBA 255
        Write-Ansi 'hello world' -RGBA 35467
        Write-Ansi 'hello world' -RGBA 0xff00ff00
    })
    
    $form.ShowDialog()
    


    \_(ツ)_/

    Wednesday, March 18, 2020 2:43 AM
  • Is there a way I can "upvote" you?

    Just mark the answer.  That upvotes, You can also upvote specific posts with the voting button.


    \_(ツ)_/

    Wednesday, March 18, 2020 2:47 AM