いわゆるキーボード入力をエミュレートするというものです。
準備
node-gypが動作する環境を整えておいてください。コンパイル環境は管理者権限のコマンドプロンプトで
npm install --global --production windows-build-tools
と実行すればできるようになります。1
必要なnpmパッケージは次の五つです。それぞれ入れてください。
- ffi
- ref
- ref-struct
- ref-union
- ref-array
ffi
がDLLを直接読み込んで実行します。ref
およびref-*
は構造体、共用体、配列などを行うのに必要になります。
コード
面倒だったのでCoffeeScriptで書いています。CoffeeScriptを知らないって人はTry CoffeeScriptで変換されたコードを見てください。2
import ref from 'ref'
import ffi from 'ffi'
import StructType from 'ref-struct'
import UnionType from 'ref-union'
import ArrayType from 'ref-array'
###
SendInput function
https://msdn.microsoft.com/library/windows/desktop/ms646310.aspx
###
# check pointer size for defined ULONG_PTR
ptrSize = ref.NULL_POINTER.length
ulongPtr = switch ptrSize
when 4
ref.types.uint32
when 8
ref.types.uint64
else
throw new Error("Supported pointer size is 4 or 8, but is #{ptrSize}")
MouseInputType = StructType
dx: ref.types.long
dy: ref.types.long
mouseData: ref.types.uint32
dwFlags: ref.types.uint32
time: ref.types.uint32
dwExtraInfo: ulongPtr
KeybdInputType = StructType
wVk: ref.types.uint16
wScan: ref.types.uint16
dwFlags: ref.types.uint32
time: ref.types.uint32
dwExtraInfo: ulongPtr
HardwareInputType = StructType
uMsg: ref.types.uint32
wParamL: ref.types.uint16
wParamH: ref.types.uint16
UnionInputType = UnionType
mi: MouseInputType
ki: KeybdInputType
hi: HardwareInputType
InputType = StructType
type: ref.types.uint32
u: UnionInputType
InputArrayType = ArrayType(InputType)
user32 = ffi.Library 'user32',
SendInput: [ref.types.uint, [ref.types.uint, InputArrayType, ref.types.int]]
# Virtual-Key Codes
# https://msdn.microsoft.com/library/windows/desktop/dd375731.aspx
keys = [0x48, 0x4F, 0x47, 0x45] # hoge
inputs = new InputArrayType(keys.length)
for vk, i in keys
inputs[i].type = 1 # INPUT_KEYBOARD
inputs[i].u.ki.wVk = vk
inputs[i].u.ki.wScan = 0
inputs[i].u.ki.dwFlags = 0
inputs[i].u.ki.time = 0
inputs[i].u.ki.dw = 0
setInterval ->
result = user32.SendInput(inputs.length, inputs, InputType.size)
console.log("send: #{result}")
, 1000
解説
SendInput関数を使用しています。Cのコードをffi
を用いて実現しているだけに過ぎません。
マウスもできると思いますが、試していません。他にもあまりテストしていませんので、うまくいかなかったら、コメント等残してくれると助かります。特に、32bit環境は試す環境が無いので、うまくいくかはかなり不安です。
終了はCtrl+Cなどで強制終了してください。
構造体、共用体、配列が組み合わさった場合にffi
にどう読み込ませるかのサンプルが全然見当たらなかったので、本当にこれでいいのかはちょっと不安です。一応、上のコードは手元では動いてはいるのですが。
参考
Node.jsでWindowsのキー状態を取得する
目的は逆ですが、ffi
の使い方の参考にさせていただきました。