見出し画像

PowerShellでキーをリアルタイムに取得する

PowerShellで何か入力を求めるとき普通はRead-hostを使います。
この方法だと、いちいちENTERキーを押す必要があります。

$KEY = read-host "なにかおす"
write-host "$KEY が押されました"

通常ならこれで十分ですが、
リアルタイムでキー入力させることは出来ないでしょうか?

Windows上のPowerShellならOS機能を全部使えるので出来るはず。

いろいろ試してみたところDLLをインポートすることでリアルタイム入力ができました。
下がサンプルです。


# DLLのインポート
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Keyboard
{
    [DllImport("user32.dll")]
    public static extern short GetAsyncKeyState(int vKey);
}
"@

# 仮想キーコード
$VK_0 = 0x30  # 数字の0キー
$VK_1 = 0x31  # 数字の1キー
$VK_2 = 0x32  # 数字の2キー
$VK_3 = 0x33  # 数字の3キー
$VK_SPACE = 0x20 # SPACEキー

# ループしてキーの状態をチェック
while ($true) {
    $keyState = [Keyboard]::GetAsyncKeyState($VK_0)
    if ($keyState -ne 0) {
        Write-Host "キー '0' が押されました。終了します。"
        break
    }
    $keyState = [Keyboard]::GetAsyncKeyState($VK_1)
    if ($keyState -ne 0) {
        Write-Host "キー '1' が押されました"
    }
    $keyState = [Keyboard]::GetAsyncKeyState($VK_2)
    if ($keyState -ne 0) {
        Write-Host "キー '2' が押されました"
    }
    $keyState = [Keyboard]::GetAsyncKeyState($VK_3)
    if ($keyState -ne 0) {
        Write-Host "キー '3' が押されました"
    }
    $keyState = [Keyboard]::GetAsyncKeyState($VK_SPACE)
    if ($keyState -ne 0) {
        Write-Host "スペースキー  が押されました"
    }
    Start-Sleep -Milliseconds 100  # 負荷を軽減するために少し待機
}

Write-Host "プログラムが終了しました。"

キーロガーも作れそうですね

関数の解説

GetAsyncKeyState関数は前に呼ばれてから次に呼ばれるまでに入力があったかどうかを判定する関数です。
GetAsyncKeyState関数にキーコードを渡して判定します。
キーコードの一覧はこちらのリンク先にあります


よく使いそうなキーコード

0x0D # エンターキー
0x20 # スペースキー
0x25 # 左キー
0x26 # 上キー
0x27 # 右キー
0x28 # 下キー
...
0x30 # 数字の0キー
0x31 # 数字の1キー
0x32 # 数字の2キー
0x33 # 数字の3キー
...
0x41 # Aキー
0x42 # Bキー
0x43 # Cキー
0x44 # Dキー
0x45 # Eキー
0x46 # Fキー
...
0x25 # 左キー
0x26 # 上キー
0x27 # 右キー
0x28 # 下キー


#PowerShell #キー入力 #リアルタイム #GetAsyncKeyState #WindowsAPI
#プログラミング学習 #プログラミング初心者 #テキストゲーム

いいなと思ったら応援しよう!