Powershell unable to find type [System.Windows.Forms.KeyEventHandler]
Asked Answered
Z

3

24

This might be a pretty simple question but I'm totally lost and searching for an answer hasn't been helpful.

I've got some powershell code to display a simple GUI with TextBoxes. Some of the textboxes allows the user to press Enter to run Button_Click code. When I try running the PS1 script, I get errors saying the following:

Unable to find type [System.Windows.Forms.KeyEventHandler].
Make sure that the assembly that contains this type is loaded.At C:\Scripts\GUI-Testing.ps1:161 char:1

$TestVar=[System.Windows.Forms.KeyEventHandler]
CategoryInfo          : InvalidOperation: (System.Windows.Forms.KeyEventHandler:TypeName)
FullyQualifiedErrorId : TypeNotFound

The strange part, if I close the GUI then re-run the script, I don't get the Unable to find type error and pressing Enter works as desired.

Thinking I had an answer, I tried using [void][reflection.assembly]::Load('System.Windows.Forms.KeyEventHandler') which give this error Exception calling "Load" with "1" argument(s): "Could not load file or assembly 'System.Windows.Forms.KeyEventHandler' or one of its dependencies. [FileNotFoundException]

Zingg answered 6/1, 2015 at 3:46 Comment(1)
I should be loading this already with [void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral')Zingg
H
40

Make sure you load the following assemblies at the top of your script:

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

If it's still not working, you could do something like:

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({
    if ($_.KeyCode -eq "Enter") 
    {    
        #Write Code Here
    }
})
Homozygote answered 6/1, 2015 at 4:48 Comment(4)
Thanks, I was going off other examples and the assemblies were being loaded under the Enter key press variables. Makes sense powershell would complain about things. Now powershell is happy! Thanks!Zingg
why not add-type -AssemblyName "System.Windows.Forms" ?Photokinesis
Neither add-type .... nor [System.Reflection.Assembly]::LoadWithPartialName(...) have any effect. Both execute w/o errors, but the Forms assembly/module is just not getting loaded.. Any hints?Swaine
@Swaine that has been deprecated, see learn.microsoft.com/en-us/dotnet/api/… The overloads of the Assembly.LoadWithPartialName method are obsolete and have been retained for backward compatibility. The non-obsolete alternative is Assembly.Load(String).Zingg
Z
0

This code opens Notepad and types "Hello"

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

add-type -AssemblyName microsoft.VisualBasic
add-type -AssemblyName System.Windows.Forms

Start-Process -FilePath "notepad.exe"
start-sleep -Milliseconds 500

[Microsoft.VisualBasic.Interaction]::AppActivate("Notepad")
start-sleep -Milliseconds 100
[System.Windows.Forms.SendKeys]::SendWait("+{h}")
start-sleep -Milliseconds 100
[System.Windows.Forms.SendKeys]::SendWait("{e}")
start-sleep -Milliseconds 100
[System.Windows.Forms.SendKeys]::SendWait("{l}")
start-sleep -Milliseconds 100
[System.Windows.Forms.SendKeys]::SendWait("{l}")
start-sleep -Milliseconds 100
[System.Windows.Forms.SendKeys]::SendWait("{o}")
start-sleep -Milliseconds 100

Here is another example below that doesn't show anything but instead sends keystroke "ctrl+schift+alt+a":

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

add-type -AssemblyName microsoft.VisualBasic

start-sleep -Milliseconds 2500

[System.Windows.Forms.SendKeys]::SendWait("(^+%{a})")
Zuckerman answered 1/12, 2022 at 9:17 Comment(1)
Simple script to run from the PowerShell CLI. Just open Powershell, browse to the directory of the script using "cd", type the name of your script (e.g. test1.ps1) and hit enter. Please note, sometimes you need to add the "Path" of the folder to your Windows System Environment Variables by typing "Path" in the Windows Search bar.Zuckerman
B
0

I couldn't get any of these working:

  • [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") ,
  • [reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral')
  • Add-Type -AssemblyName 'System.Windows.Forms'

But by resorting to a wildcard path search, I was able to get things working with:

$framework = "C:\Windows\Microsoft.NET\Framework$(if([Environment]::Is64BitProcess){'64'})\v4.0.*";
[Reflection.Assembly]::LoadFrom(("$framework\System.Drawing.dll" | Resolve-Path).ToString())
[Reflection.Assembly]::LoadFrom(("$framework\System.Windows.Forms.dll" | Resolve-Path).ToString())
[Reflection.Assembly]::LoadFrom(("$framework\Microsoft.VisualBasic.dll" | Resolve-Path).ToString())
[Reflection.Assembly]::LoadFrom(("$framework\*\PresentationFramework.dll" | Resolve-Path).ToString())

enter image description here

Bracteate answered 11/1 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.