Powershell-Skript für Tastenkombinationen?
Ich hätte gerne ein Skript, der es so macht, wenn er läuft, mehrere Tastenkombinationen ausführt, wenn mach eine Tastenkombination auslößt!
Bitte nochmal auf deutsch.
hab ich
1 Antwort
Ich hätte gern 100€ 😅
Im Ernst, wir geben hier Hilfe zur Selbsthilfe und erledigen keine Auftragsarbeiten.
Powershell für sich alleine kann sowas nicht. Wir müssen auf eine Funktion der SystemAPI zurückgreifen.
Im folgenden polle ich einfach stumpf alle 40 Millisekunden ob die gewünschten (Auslöser)Tasten gedrückt sind.
Auf globale Tastenkombie warten:
#https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
$signature = @'
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern short GetAsyncKeyState(int virtualKeyCode);
'@
$API = Add-Type -MemberDefinition $signature -Name 'Keypress' -Namespace API -PassThru
#https://learn.microsoft.com/de-de/windows/win32/inputdev/virtual-key-codes
#Tastenkombie festlegen
$InitiatorKey = 0xA4 #VK_LMENU (ALT)
$SecondKey = [byte][char]$('X').ToUpper() #Taste X
#most significant Bit und the least significant Bit:
#Echtzeitstatus: Taste wird gedrückt gehalten (0x8000) MSB
#Die Taste ist gerade vom losgelassenen zum gedrückten Zustand übergegangen (0x0001) LSB
$significantBits = 0x8001 #MSB and LSB
#polle alle 40 Millisekunden die definierten Tasten
do {Start-Sleep -Milliseconds 40} until (
(($API::GetAsyncKeyState($InitiatorKey) -band $significantBits) -ne 0 ) -band #bis $InitiatorKey (hier ALT-Taste) gedückt wird
($API::GetAsyncKeyState($SecondKey) -ne 0) #und auch $SecondKey (hier X)
)
Write-Host 'ALT+X wurde gedrueckt' -fo green
Polling ist natürlich nicht unbedingt Resoucenfreundlich. Das Zweite Manko, wäre, dass die abzufragende Tastenkombination nicht von einer anderen Anwendung definiert sein darf! Ist dies der Fall, wäre es ein Lotteriespiel, wer die Tasten als erstes erkennt.
Die Alternative wäre ein KeyboardHook Allerdings birgt ein solcher Eingriff in die Ereigniskette auch die Gefahr, dass dieser von der AV-Software als Keylogger moniert wird. Zudem ist es wesentlich mehr Aufwand.
Was letztlich passieren soll, ist das generieren von Tastendrücken mit der Methode SendWait() der Klasse System.Windows.Forms.SendKeys. Beacht, das es der Methode egal ist wer gesendeten Tasten empfängt. Das Fenster , welches den Focus hat, verarbeitet sie (oder auch nicht).
Tastedrücke senden:Add-Type -AssemblyName 'System.Windows.Forms'
#https://learn.microsoft.com/de-de/dotnet/api/system.windows.forms.sendkeys?view=windowsdesktop-8.0
$WSK = [System.Windows.Forms.SendKeys]
#Tastenbuffer leeren (falls noch was drin ist)
$WSK::Flush()
Start-Sleep -Milliseconds 1000 #wichtig!!!, Flush() ist asynchron, gib etwas Zeit , bis etwas in den Tastaturpuffer schreibst, sonst wird es von Flusch "geressen"
#liste der (Send)Tastencode Definitionen: https://learn.microsoft.com/de-de/dotnet/api/system.windows.forms.sendkeys?view=windowsdesktop-8.0#remarks
$WSK::SendWait('blah und &blub {Enter}') #sende eine Textzeile + ENTER
$WSK::SendWait('^+stestdatei.txt{Enter}') #sende CTRL+SHIFT+S und eien Dateinamen und ENTER (entspräche im Notepad dem Speichern unter Dialog)
oder:
Add-Type -AssemblyName 'System.Windows.Forms'
$WSK = [System.Windows.Forms.SendKeys]
$WSK::Flush()
Start-Sleep -Milliseconds 1000
#mehre zu sendende Strings einzeln in einem Array definieren...
$KeysToSend = @(
'Muh und Miff {Enter}', #text schreiben
'^+s', #Speichern unter...-dialog öffnen
'testdatei.txt{Enter}' #...ausfüllen
'%{F4}' #Programm beenden
)
#...und die Elemente via ForEach verarbeiten
$KeysToSend|
ForEach-Object{
$WSK::SendWait($_)
Start-Sleep 1 #optional Pause zwischen den zu sendenden Strings
}
noch mal alles beisammen:
demo.ps1
$signature = '[DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern short GetAsyncKeyState(int virtualKeyCode);'
$API = Add-Type -MemberDefinition $signature -Name 'Keypress' -Namespace API -PassThru
$InitiatorKey = 0xA4
$SecondKey = [byte][char]$('X').ToUpper()
$significantBits = 0x8001
do {Start-Sleep -Milliseconds 40} until (
(($API::GetAsyncKeyState($InitiatorKey) -band $significantBits) -ne 0 ) -band ($API::GetAsyncKeyState($SecondKey) -ne 0)
)
Add-Type -AssemblyName 'System.Windows.Forms'
$WSK = [System.Windows.Forms.SendKeys]
$WSK::Flush()
Start-Sleep -Milliseconds 1000
$WSK::SendWait('blah und &blub {Enter}'
$WSK::SendWait('^+stestdatei.txt{Enter}')
Letztlich sind solche "Spielereien" eine ziemlich unsichere Angelegenheit, weil die verwendeten Methoden keinerlei Kontrolle über ihre Umgebung haben. Sowas nenne ich Blindflug.
Die WindowsTaste Kann man weder Lesen noch Senden !!!