Вызовите Windows SetWinEventHook из nodejs - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь вызвать SetWinEventHook , как описано здесь для C # , но из nodejs.

Я использую ffi-napi привязать к функции.Вот мой код:

const ffi = require("ffi-napi")

const user32 = ffi.Library("user32", {
    SetWinEventHook: ["int", ["int", "int", "pointer", "pointer", "int", "int", "int"]]
})

const pfnWinEventProc = ffi.Callback("void", ["pointer", "int", "pointer", "long", "long", "int", "int"],
    function (hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime) {
        console.log("Callback!")
        console.log(arguments)
    })

const EVENT_SYSTEM_FOREGROUND = 3
const WINEVENT_OUTOFCONTEXT = 0
const WINEVENT_SKPIOWNPROCESS = 2

user32.SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, null, pfnWinEventProc,
    0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKPIOWNPROCESS)

setInterval(function () {
    // keep the script alive
}, 500)

process.on("exit", function () {
    console.log("Exiting")
    pfnWinEventProc
})

Проблема в том, что мой обратный вызов не вызывается.Он должен вызываться всякий раз, когда изменяется фокусное окно.

Я также не получаю никаких ошибок, поэтому совершенно не понимаю, что я делаю здесь неправильно.

Код здесь также, если вы хотите проверить это.

1 Ответ

0 голосов
/ 21 декабря 2018

Наконец-то я заработал, используя комбинацию кластерного модуля (если вы не хотите блокировать цикл событий с помощью цикла сообщений) и заглядывая в часть Windows активногоВыигрышный пакет .

Полный код здесь .

const ffi = require("ffi-napi")
const cluster = require("cluster")
const ref = require("ref")
const wchar = require("ref-wchar")

if (cluster.isMaster) {
    console.log("Main code here...")
    cluster.fork()
} else {
    const msgType = ref.types.void
    const msgPtr = ref.refType(msgType)
    const EVENT_SYSTEM_FOREGROUND = 3
    const WINEVENT_OUTOFCONTEXT = 0
    const WINEVENT_SKPIOWNPROCESS = 2

    const user32 = ffi.Library("user32", {
        SetWinEventHook: ["int", ["int", "int", "pointer", "pointer", "int", "int", "int"]],
        GetWindowTextW: ["int", ["pointer", "pointer", "int"]],
        GetWindowTextLengthW: ["int", ["pointer"]],
        GetMessageA: ["bool", [msgPtr, "int", "uint", "uint"]]
    })

    function getMessage() {
        return user32.GetMessageA(ref.alloc(msgPtr), null, 0, 0)
    }

    const pfnWinEventProc = ffi.Callback("void", ["pointer", "int", "pointer", "long", "long", "int", "int"],
        function (hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime) {
            const windowTitleLength = user32.GetWindowTextLengthW(hwnd)
            const bufferSize = windowTitleLength * 2 + 4
            const titleBuffer = Buffer.alloc(bufferSize)
            user32.GetWindowTextW(hwnd, titleBuffer, bufferSize)
            const titleText = ref.reinterpretUntilZeros(titleBuffer, wchar.size)
            const finallyWindowTitle = wchar.toString(titleText)
            console.log(finallyWindowTitle)
        }
    )

    user32.SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, null, pfnWinEventProc,
        0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKPIOWNPROCESS)

    let res = getMessage()
    while(res != 0) {
        switch (res) {
            case -1:
                console.log("Invalid GetMessageA arguments or something!");
                break
            default:
                console.log("Got a message!")
        }
        res = getMessage()
    }
}
...