Utilisation de SendInput dans Node-FFI

Je voulais utiliser la fonction SendInput à partir de Windows Api dans nodejs, à l’aide du package FFI.

Ma connaissance du C étant limitée, je ne peux donc pas vraiment comprendre le problème que j’ai. J’essaie essentiellement d’appuyer virtuellement sur une touche du clavier.

C’est le code que j’ai:

var ffi = require('ffi'); var ref = require ('ref'); var struct = require ('ref-struct'); var keyboardInput = struct({ 'type': 'int', 'wVK': 'int', 'wScan': 'int', 'dwFlags': 'int', 'time': 'int', 'dwExtraInfo': 'int64' }); var keyboardInputPtr = ref.refType(keyboardInput); var keyboard = new keyboardInput(); keyboard.type = 1; keyboard.wVK = 0x41; keyboard.wScan = 0; keyboard.dwFlags = 2; keyboard.time = 0; keyboard.dwExtraInfo = 0; var user32 = ffi.Library('user32', { 'SendInput': [ 'int', [ 'uint', keyboardInputPtr, 'int' ] ] }); setInterval(function(){ var r = user32.SendInput(1, keyboard.ref(), 40); console.log(r); }, 500); 

Il me connecte un “1” dans la console, cela ne signifie-t-il pas que cela fonctionne? Parce que je n’obtiens pas de touche lorsque j’ouvre le bloc-notes.

Le “1” vous indique qu’un événement a été inséré et non ce qu’il est réellement. Je ne sais pas à propos de FFI mais il me semble que keyboardInput a des définitions de type non valides. wVK et wScan doivent être des entiers sur 16 bits (d’où le «w» pour WORD). Comme ils sont tapés de la même manière que dwFlags (un «int»), cela entraîne des valeurs d’entrée non valides.

J’ai enfin trouvé un moyen d’utiliser node-ffi pour saisir des touches à l’aide de la fonction SendInput!

Toutefois, notez qu’il existe deux manières d’appeler la fonction SendInput, comme indiqué ici: https://autohotkey.com/boards/viewtopic.php?p=213617#p213617

Dans mon cas, je devais utiliser la deuxième approche (code de balayage), car la première approche (clé virtuelle) ne fonctionnait pas dans le jeu pour lequel j’avais besoin de la simulation de clé. L’appel de la fonction avec asScanCode = false n’a donc pas encore été testé.

Sans plus tarder, voici la solution complète:

 import ffi from "ffi"; import ref from "ref"; import StructType from "ref-struct"; var arch = require("os").arch(); var intPtr = ref.refType("int"); var Input = StructType({ "type": "int", // For some reason, the wScan value is only recognized as the wScan value when we add this filler slot. // It might be because it's expecting the values after this to be inside a "wrapper" substructure, as seen here: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx "???": "int", "wVK": "short", "wScan": "short", "dwFlags": "int", "time": "int", "dwExtraInfo": "int64" }); var user32 = ffi.Library("user32", { SendInput: ["int", ["int", Input, "int"]], //MapVirtualKeyEx: ["uint", ["uint", "uint", intPtr]], }); function ConvertKeyCodeToScanCode(keyCode: number) { let keys = "**1234567890-=**qwertyuiop[]**asdfghjkl;'`*\\zxcvbnm,./".split(""); return keys.indexOf(Ssortingng.fromCharCode(keyCode).toLowerCase()); } const INPUT_KEYBOARD = 1; const KEYEVENTF_EXTENDEDKEY = 0x0001; const KEYEVENTF_KEYUP = 0x0002; const KEYEVENTF_UNICODE = 0x0004; const KEYEVENTF_SCANCODE = 0x0008; const MAPVK_VK_TO_VSC = 0; export function KeyToggle(keyCode: number, type = "down" as "down" | "up", asScanCode = true) { let entry = new Input(); entry.type = INPUT_KEYBOARD; entry.time = 0; entry.dwExtraInfo = 0; // (virtual) key-code approach if (!asScanCode) { entry.dwFlags = type == "down" ? 0 : KEYEVENTF_KEYUP; entry.wVK = keyCode; entry.wScan = 0; } // scan-code approach else { //let scanCode = user32.MapVirtualKeyEx(keyCode, MAPVK_VK_TO_VSC); // this should work, but it had a Win32 error (code 127) for me let scanCode = ConvertKeyCodeToScanCode(keyCode); entry.dwFlags = type == "down" ? KEYEVENTF_SCANCODE : KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; entry.wVK = 0; entry.wScan = scanCode; } let result = user32.SendInput(1, entry, arch === "x64" ? 40 : 28); console.log(`Number of key-events added: ${result}`); } export function KeyTap(keyCode: number, asScanCode = true) { KeyToggle(keyCode, "down", asScanCode); KeyToggle(keyCode, "up", asScanCode); } 

Pour l’utiliser, appelez:

 KeyTap(65); // press the A key 

Ou, si vous utilisez le package keycode npm :

 import keycode from "keycode"; KeyTap(keycode.codes.a);