Home > Blockchain >  Powershell user input
Powershell user input

Time:09-30

I have been trying to make a small script that takes user input and inserts "-" as such: aaaaa-bbb-ccc-ddd While also allowing backspace. I managed to make this in Python pretty handily, but whenever I make it into an EXE, Windows thinks it is a virus so I went to Powershell.

Anyway, the issue I have is that it will do aaaaa-bbbb-cccc-d instead of the desired aaaaa-bbb-ccc-ddd. For some reason it is not going to 3 but 4 after the first 5. Big shout out to u/frmadsen for helping me so far. This is the code:

[Console]::TreatControlCAsInput = $true
[Console]::WriteLine("Enter Serial:")

$inputString = ""
$maxGroupCount = 5 # max number of groups
$groupSize = 5 # chars per group
$groupCount = 0
$maxLength = $maxGroupCount*$groupSize   $maxGroupCount-1
$abort = $false

do{
    $keyInfo = [Console]::ReadKey($true)

    # Handle Escape key.
    if($keyInfo.Key -eq "Escape"){
        $abort = $true
        break
    }

    # ignore some keys...
    if(($keyInfo.Modifiers -band [System.ConsoleModifiers]::Alt) -eq         
[System.ConsoleModifiers]::Alt -or
       ($keyInfo.Modifiers -band [System.ConsoleModifiers]::Control) -eq 
[System.ConsoleModifiers]::Control -or
       $keyInfo.Key -eq "Tab" -or
       $keyInfo.KeyChar -eq '`0'
       ){ continue }

    # Handle backspace.
    if($keyInfo.Key -eq "Backspace"){
        # Are there any characters to erase?
        if($inputString.Length -ge 1){
            # Determine where we are in the console buffer.
            $oldLength = $inputString.Length
            $removeLen = 1

            # are we erasing a group separator?
            if($inputString.EndsWith('-')){
                # remove '-' and the char before it
                $removeLen = 2
                $groupCount--
            }

            $cursorCol = [Console]::CursorLeft - $removeLen
            $inputString = $inputString.Substring(0, $oldLength - $removeLen)
            [Console]::CursorLeft = 0
            [Console]::Write($inputString   ' '*($oldLength - $inputString.Length))
            [Console]::CursorLeft = $cursorCol
        }
        continue
    }

    # code must not exceed maximum length

        if($inputString.Length -ge 17){
        continue
    }

    $lastChar = $keyInfo.KeyChar
    [Console]::Write($lastChar)
    $inputString  = $lastChar

    if(($inputString.Length) % $groupSize -eq 0 -and $lastChar.Length -lt 17){
        # add group separator now
        $groupCount  
        $inputString  = '-'
        [Console]::Write('-')

        }

    if(($inputString.Length) % $groupSize -eq 0 -and $lastChar.Length -lt 17){
        # add group separator now
        $groupSize = 3
        $inputString = 0
        $groupCount  
        $inputString  = '-'
        [Console]::Write('-')
    
       }
  

}while($keyInfo.Key -ne "Enter")

[Console]::WriteLine("")

if(!$abort){
    "User wrote: $inputString"
}else{
    "User aborted"
}

CodePudding user response:

You have a logic error. The length is including the dashes you add to the input. Therefore, you should be checking $lastChar.Length is less than 19, not 17.

# here is line 54, above is unchanged
        if($inputString.Length -ge 19){
        continue
    }

    $lastChar = $keyInfo.KeyChar
    [Console]::Write($lastChar)
    $inputString  = $lastChar

    if(($inputString.Length) % $groupSize -eq 0 -and $lastChar.Length -lt 19){
        # add group separator now
        $groupCount  
        $inputString  = '-'
        [Console]::Write('-')

        }

    if(($inputString.Length) % $groupSize -eq 0 -and $lastChar.Length -lt 19){
        # add group separator now
        $groupSize = 3
        $inputString = 0
        $groupCount  
        $inputString  = '-'
        [Console]::Write('-')
    
       }
  

}while($keyInfo.Key -ne "Enter")
# Unchanged below

CodePudding user response:

As suggested in the comment, it is probably easier to replace the whole $InputString with a regular expression:

[Console]::TreatControlCAsInput = $true
[Console]::WriteLine("Enter Serial:")

$inputString = ''
$ValidCharacters = '\w'
$Size = 14
$Dots = '.' * $Size
$abort = $false

do{
    $keyInfo = [Console]::ReadKey($true)
    if($keyInfo.Key -eq "Escape"){
        $abort = $true
        break
    }
    if($inputString.Length -ge 1 -and $keyInfo.Key -eq "Backspace"){ $InputString = $InputString.SubString(0, ($InputString.Length - 1)) }
    elseif($inputString.Length -lt $Size -and $keyInfo.Key -Match $ValidCharacters) { $inputString  = $keyInfo.KeyChar }
    $Write = [regex]::Matches(($inputString   $Dots), '^([^-]{5})([^-]{3})([^-]{3})([^-]{3})').Groups[1..4].Value -Join '-'
    [Console]::CursorLeft = 0
    [Console]::Write($Write)

}while($keyInfo.Key -ne "Enter")

[Console]::WriteLine("")

if(!$abort){
    "User wrote: $Write"
}else{
    "User aborted"
}
  • Related