Home > Software design >  Is there a way to fix the enter and delete keys in [Console]::ReadKey() in powershell
Is there a way to fix the enter and delete keys in [Console]::ReadKey() in powershell

Time:10-30

I have a script here:

Clear-Host
$Word = [String]::Empty
$Mode = "INSERT MODE"
While ($True) {
    $E = [Console]::ReadKey($True)
    If ($E.Key -eq "Escape") {
        Break
    }
    If ($E.Key -eq "Enter") {
        Write-Host `n
        $Word  = "`n"
    }Else {
        $Word  = $E.KeyChar
        Write-Host $E.KeyChar -NoNewLine
    }
}
Clear-Host
Return $Word

It is supposed to read the user's keypresses and then print them out onto the screen, and it works fine apart from the backspace and enter keys. Enter prints two newlines and backspace moves the pointer backwards and just overwrites the character like this:

Hello worle_ (Spelling Error)
Hello worle̲ (Pressed backspace)
Hello world_ (Just overwrote the letter as if it wasn't there)

How can I get enter to print one newline and properly use backspaces? I'm on powershell 5.1 and using windows 10.

CodePudding user response:

I would suggest leveraging the .NET assembly "System.Windows.Forms".

Add-Type -AssemblyName System.Windows.Forms

[System.Windows.Forms.SendKeys]::SendWait("Hello")
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
[System.Windows.Forms.SendKeys]::SendWait("World")
[System.Windows.Forms.SendKeys]::SendWait("{Enter}")

You can find other special characters here.

CodePudding user response:

Try the following:

$word = ''
$mode = 'INSERT MODE'
$done = $false
While (-not $done) {
    $e = [Console]::ReadKey($true)
    switch ($e.Key) {
      'Escape' { $done = $true; break }
      'Enter' {  $word  = "`n"; Write-Host; break }
      'Backspace' { 
        if ($word.Length) { $word = $word.Substring(0, $word.Length-1) } 
        Write-Host -NoNewLine "`b `b"
        break 
      }
      default {  $word  = $e.KeyChar; Write-Host -NoNewLine $e.KeyChar }
    }
}

Write-Host

# Output the captured input.
"[$word]"
  • To emit just a single newline, simply use Write-Host without arguments.

  • To emulate interactive backspace behavior, emit a backspace, then a space, followed by another backspace.

    • By default, emitting a backspace character to the console is non-destructive: that is, the cursor moves one position back, but doesn't erase the character at the previous cursor position.
    • The technique above makes it appear as if the character was erased, by replacing it with a space.
  • Related