0

I have a sample script for my diploma and it uses keypress mechanism, like so:

echo "A text prompting you to pres Enter" 
$key = [System.Windows.Input.Key]::Enter


do
{
$isCtrl = [System.Windows.Input.Keyboard]::IsKeyDown($key)
if ($isCtrl)
{
$query = Get-Childitem 'D:\' -Recurse | Where-Object {$_.Name -match "controller.st$"}
foreach-object { $name = $query.FullName}

(Get-Content $name).Replace('A := AND55_OUT OR AND56_OUT OR AND61_OUT;', 'A := AND55_OUT') | Set-Content $name 
#this actually does the replacing in a file

echo "sample text"

Start-Sleep -Seconds 30

echo "sample text"

break
}
} while ($true)

and the rest of the script continues.

I use the converting script

function Convert-PowerShellToBatch
{
    param
    (
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [string]
        [Alias("FullName")]
        $Path
    )
 
    process
    {
        $encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content -Path $Path -Raw -Encoding UTF8)))
        $newPath = [Io.Path]::ChangeExtension($Path, ".bat")
        "@echo off`npowershell.exe -NoExit -encodedCommand $encoded" | Set-Content -Path $newPath -Encoding Ascii
    }
}
 
Get-ChildItem -Path C:\path\to\powershell\scripts -Filter *.ps1 |
  Convert-PowerShellToBatch

and I modify this to my case but when I run the batch file, I get the following error:

Unable to find type [System.Windows.Input.Keyboard].
At line:7 char:11
+ $isCtrl = [System.Windows.Input.Keyboard]::IsKeyDown($key)
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Windows.Input.Keyboard:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

What can I do to overcome this?

  • I am not understanding how your problem relates to a [tag:batch-file]. Could you please explain. – Squashman Apr 16 '21 at 16:32
  • @Squashman the converter turns my .ps1 file into a .bat file, therefore it becomes a batch file. – thewantedgun Apr 16 '21 at 16:35
  • 1
    [`System.Windows.Input.Keyboard`](https://learn.microsoft.com/dotnet/api/system.windows.input.keyboard?view=netframework-4.8) lives in `PresentationCore.dll`, so you'll probably need an `Add-Type -Assembly PresentationCore` before this works. – Jeroen Mostert Apr 16 '21 at 16:36
  • 2
    "when I use the converting script" - what converting script? – Mathias R. Jessen Apr 16 '21 at 16:37
  • @thewantedgun, please take some time to read the [tour]. Then read [ask] a good question. And finally please provide a [mcve] of all the code you are using. Your question is lacking in a lot of necessary information. – Squashman Apr 16 '21 at 16:38
  • @MathiasR.Jessen https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/converting-powershell-to-batch – thewantedgun Apr 16 '21 at 16:39
  • 1
    I suspect it just puts your powershell script in a batch wrapper. It's still ultimately a powershell script, especially since not everything in powershell has a batch equivalent. – SomethingDark Apr 16 '21 at 16:44
  • @Squashman I provided the whole code. – thewantedgun Apr 16 '21 at 16:46
  • @SomethingDark yes it is. I'm just not a software developer to begin with, though I have some education but I needed to code this in order to provide an actual task for my diploma. This is only 1/4 of the task that I did. – thewantedgun Apr 16 '21 at 16:47
  • 1
    Since your unwrapped powershell script works correctly, the issue is located somewhere in the converted script. Since you haven't posted that script in your question, I have no way of troubleshooting your issue. – SomethingDark Apr 16 '21 at 16:52
  • @thewantedgun what about the batch file code? If your code works fine running from Powershell without the base64 conversion, then the problem lies most likely in the code that makes the base64 conversion or how it is getting executed in the batch file. – Squashman Apr 16 '21 at 16:52
  • @Squashman I also provided the link here in the comments but I embedded the conversion code in my question too now. – thewantedgun Apr 16 '21 at 16:57
  • You need to stop commenting, and instead [edit] your post to add the details you've been asked (repeatedly) to provide. Until you've done so, I've voted to close your question because it needs details and clarity. – Ken White Apr 16 '21 at 16:59
  • I did 3 edits while I was commenting here :) – thewantedgun Apr 16 '21 at 17:06

1 Answers1

1

tl;dr

As Jeroen Mostert notes in a comment, you need to load the assembly containing types System.Windows.Input.Key and System.Windows.Input.Keyboard into your script before you can use them, using Add-Type:

Add-Type -AssemblyName PresentationCore

echo "A text prompting you to press Enter" 
$key = [System.Windows.Input.Key]::Enter

# ... the rest of your script.

The conversion script is nifty, but it cannot detect such problems.

Before converting, you should always run your script in a new session started with -NoProfile, so as to ensure that the script doesn't accidentally rely on side effects from the current session, such as the required assembly having been loaded by different code beforehand:

# Run the script in a pristine session to ensure that it is self-contained.
powershell -noprofile -file somescript.ps1

In particular, use of the ISE may have hidden the problem in your case, as these types are available in ISE sessions by default (because the ISE is built on WPF, which these types belong to) - unlike in regular console windows.

This is just one of the behavioral difference between the ISE and regular console windows], which makes the ISE - as convenient as it is - problematic. Additionally, the ISE is no longer actively developed and cannot run PowerShell (Core) v6+ - see the bottom section of this answer for details.

Consider Visual Studio Code, combined with its PowerShell extension, as the actively maintained alternative.

mklement0
  • 382,024
  • 64
  • 607
  • 775