wilix-team / iohook

Node.js global keyboard and mouse listener.
https://wilix-team.github.io/iohook
MIT License
1.2k stars 291 forks source link

Can't use iohook on a simple node app #275

Open denyncrawford opened 3 years ago

denyncrawford commented 3 years ago

Expected Behavior

Make it run on a simple node app.

Current Behavior

Showing this message and closing porcess:

refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).

Steps to Reproduce (for bugs)

  1. Use node 15.x
  2. Run npm install iohook --save
  3. node run index.js
  4. Use node 10.x
  5. Do step 2
  6. Do step 3

index.js:

const ioHook = require('iohook')

ioHook.on('keydown', key => {
  console.log(key)
})

ioHook.start(true);

Context

I'm trying to run a simple node application but it shows that message and closes the process. I changed the node version to 10.9.0 and reinstalled the module, and nothing happens.

[EDIT]: When run as a test script, it shows that the test failed. But you don't see an error message.

Your Environment

Nick-Riggs commented 3 years ago

I'm getting this as well with exactly the same output. It should be noted that all that is required to duplicate this issue is to require('iohook');

sancarn commented 3 years ago

Yep having the same problem. Bare in mind the index.js supplied is wrong (has numerous mistakes in it). Heres an example with no mistakes which still doesn't work:

'use strict';

const ioHook = require('iohook');

ioHook.on('mousemove', event => {
  console.log(event);              // { type: 'mousemove', x: 700, y: 400 }
});

// Register and start hook
ioHook.start();

I too get the same message:

refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).
Djiit commented 3 years ago

Hey @sancarn , thanks for your message. What about submitting a PR with your suggested changes so everyone can benefits from your findings ? Thanks.

sancarn commented 3 years ago

@Djiit Erm I haven't fixed the issue? I only 'fixed' the code example supplied by @denyncrawford. I.E. They used key => code and incorrect capitalisation ioHook = ... --> iohook.on --> ioHook.start.

The code sample still doesn't actually do anything apart from log the 3 messages stated. But the initial code sample had no hope of working either.

sancarn commented 3 years ago

Did some searching. Found that the error occurs on require("iohook") (initial load). The crash appears to occur within the constructor of IOHook class, when this.load() is called, which in turn calls NodeHookAddon.startHook(this._handler.bind(this), this.debug || false);.

Unfortunately, i did look through the C code but can't even find where the following messages are logged:

refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).

So can't really help from here. Will need one of the devs who knows what's going on to explain what's going on...

sancarn commented 3 years ago

Note: We can't even do the following:

try {
   iohook = require("iohook")
} catch {
   ...
}

And with modern import iohook from "iohook" standards we can't use try like that anyway. Ideally the node app should have no way of crashing on initialisation and I'm not totally sure why the hook starts on startup either...? Shouldn't it only occur when we call start()? And shouldn't this crash be somehow detectable?

denyncrawford commented 3 years ago

Yep having the same problem. Bare in mind the index.js supplied is wrong (has numerous mistakes in it). Heres an example with no mistakes which still doesn't work:

'use strict';

const ioHook = require('iohook');

ioHook.on('mousemove', event => {
  console.log(event);              // { type: 'mousemove', x: 700, y: 400 }
});

// Register and start hook
ioHook.start();

I too get the same message:

refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).

Haha, you're right, but that's not the problem. I probably copied the mixed code from the two tests I was doing. I proceed to edit, thank you.

marcelblum commented 3 years ago

@sancarn those log messages are from this function https://github.com/wilix-team/iohook/blob/e584b64aa0dcc0e2f9acc5f5dab37fe7241c4c68/libuiohook/src/windows/input_helper.c#L469

And they are not errors in and of themselves rather they are expected log output. While they're not an indication of an error they at least show how far the lib gets before crapping out.

I was able to reproduce this issue on Windows 10 but only on one version of Node that I tried, latest stable Node v14.x (83). In all earlier Node versions I tried iohook worked using the prebuilt binaries (nb: I didn't test every single Node version). So there may be something with changes in latest Node that lead iohook to cause the process to exit silently like that. Needs further investigation, I'm not an expert on this project but I'll try to take a deeper look when I get a chance.

One question, are you using the prebuilt binaries or did you build them yourself?

marcelblum commented 3 years ago

Update: looks like it's working fine in all Node versions <= 13.x but fails silently in >= 14.x. Appears to be a Windows Node 14+ only issue.

ghost commented 3 years ago

I'm having a similar problem on Linux Mint 20 with Node 14, it simply exits without any errors or messages. I've tried this script:

const ioHook = require('iohook');

ioHook.on('keydown', (event) => {
  console.log(event);
});

ioHook.start(true);

Not sure if this is related to this issue or to https://github.com/wilix-team/iohook/issues/268, but installing a previous version worked for me: npm install iohook@0.6.6 --save.

denyncrawford commented 3 years ago

Any possible fix or update related to this issue, without downgrading node?

TheMrGong commented 3 years ago

Any possible fix or update related to this issue, without downgrading node?

@denyncrawford I was able to get this functional on node v14 by using v0.6.6 of the library. It seems that versions past that (0.7.x) are broken.

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ npm add iohook@0.7.0

[removed adding logging]

+ iohook@0.7.0

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ node index.js
refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).
[exits with no message]

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ npm remove iohook

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ npm remove iohook && npm add iohook@0.6.6

[removed removal & adding logging]

removed 148 packages and audited 10 packages in 1.031s
+ iohook@0.6.6

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ node index.js
refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).
Connected to device!
Data received

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ node -v
v14.0.0
denyncrawford commented 3 years ago

@TheMrGong Nice :D I'll check it, thanks!

amoschoomy commented 3 years ago

@TheMrGong Doesn't work for node v15>=

TheMrGong commented 3 years ago

@amoschoomy I had to compile iohook myself for node 15, it worked then

bomeers commented 3 years ago

@amoschoomy I had to compile iohook myself for node 15, it worked then

could you give us a run through on how to compile yourself?

TheMrGong commented 3 years ago

could you give us a run through on how to compile yourself?

@bomeers I followed the instructions from the documenation

bomeers commented 3 years ago

could you give us a run through on how to compile yourself?

@bomeers I followed the instructions from the documenation

Completely missed that one. Thank you

bomeers commented 3 years ago

@TheMrGong I'm looking at the docs and this caught my eye:

Install: msys2 with autotools, pkg-config, libtool, gcc, clang, glib, C++ Build Tools, cmake

Do I have to install all of these or just one of them?

marcelblum commented 3 years ago

@bomeers I think that info is out of date for Windows since this proj doesn't use cmake anymore. If you installed Node.js with the "install tools for native modules" box checked you should already have all the prereqs needed, if not you can follow the instructions for node-gyp https://github.com/nodejs/node-gyp#on-windows.

bomeers commented 3 years ago

@marcelblum I've got that box checked and I started going through the steps to create the iohook.node file. Seems I ran into a common error:

internal/modules/cjs/loader.js:883
  throw err;
  ^

Error: Cannot find module 'fs-extra'
Require stack:
- C:\<file_path>\node_modules\iohook\build.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (C:\<file_path>\node_modules\iohook\build.js:2:12)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) {
  code: 'MODULE_NOT_FOUND',

I got around this by using the command npm remove fs-extra and npm install fs-extra@9.1.0 --save-dev. This led me to another error however:

Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
  logger.c
c1 : fatal error C1083: Cannot open source file: '..\libuiohook\src\logger.c': No such file or directory [C:\<file_path>\node_modules\iohook\build\uiohook.vcxproj]
gyp ERR! build error 
gyp ERR! stack Error: `C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onExit (C:\<file_path>\node_modules\iohook\node_modules\node-gyp\lib\build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:315:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)
gyp ERR! System Windows_NT 10.0.19041
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\<file_path>\\node_modules\\iohook\\node_modules\\node-gyp\\bin\\node-gyp.js" "configure" "rebuild" "--target=4.0.4" "--arch=x64" "--dist-url=https://atom.io/download/electron" "--msvs_version=2017"
gyp ERR! cwd C:\<file_path>\node_modules\iohook
gyp ERR! node -v v14.15.5
gyp ERR! node-gyp -v v7.1.2
gyp ERR! not ok
Error: Failed to build...
    at ChildProcess.<anonymous> (C:\<file_path>\node_modules\iohook\build.js:148:23)
    at ChildProcess.emit (events.js:315:20)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)
marcelblum commented 3 years ago

@bomeers sounds like maybe you didn't do a full npm install from iohook's root before npm run build?

bomeers commented 3 years ago

@marcelblum Tried this and had the same result:

cd .\node_modules\iohook\
npm install
npm run build
marcelblum commented 3 years ago

ok i think i see the problem you are trying to build from the files that come down the pipe when you npm install iohook but that doesn't include the full iohook source. What you need to do is clone the iohook git repo. Then npm install from the root of your local copy of the repo... then npm run build

bomeers commented 3 years ago

@marcelblum That worked for me. So the build went through and created a folder called build. Do I just paste that in my node_module in my other project?

marcelblum commented 3 years ago

@bomeers no - you'd need to copy 2 files that you just built iohook.node and uiohook.dll (created in build) into your other project's node_modules\iohook\builds\node-v[WhateverVersionYouBuiltFor]-win32-x64\build\Release

bomeers commented 3 years ago

@marcelblum getting closer... I moved those two files over and tried to re-run my project. ran into this error:

image

marcelblum commented 3 years ago

@bomeers sorry to disappoint but I haven't yet been able to get latest iohook 0.7.2 working with Node v.15 (ABI 88) on Windows. Rereading the above, I think what @TheMrGong was saying is that in order to get iohook working in Node 15 he used the older iohook v0.6.6 codebase to build for a target of Node 15 and that worked (correct me if I'm wrong @TheMrGong). iohook switched to using node-gyp from cmake after v0.6.6 and while that brought benefits such as latest electron support, it also introduced issues with building for Node 14+ which remain unresolved.

TheMrGong commented 3 years ago

@marcelblum That is correct, the build I made was with version 0.6.6.

bomeers commented 3 years ago

@marcelblum @TheMrGong Very unfortunate. So I wouldn't be able to compile 0.6.6 the same way? (with the install tools for native modules)

marcelblum commented 3 years ago

@bomeers right, you'd need the old prereqs mentioned in those old docs you had linked to earlier to build from iohook v0.6.6 with cmake. Very sorry to lead you down a time wasting path, I thought you were trying to build the latest version.

Honestly this issue with Node 14+/iohook when built with node-gyp has gotta be something stupid simple. Just needs someone with the time & expertise to look into it. I was hoping to try to take a stab when I have some more time but I don't have as much of the expertise.

Strikeeaglechase commented 3 years ago

Any work on this? The documentation/GitHub doesn't mention it anywhere but in its current state the package is unusable for the current version of node

Durss commented 3 years ago

I was using the v0.6.6 that was avoiding this issue, but it seems this version has been removed from the latest release which breaks the install of this version :(

Durss commented 3 years ago

I tried to rebuild from the GIT repo with no change to the behavior after simply installing the latest version of the module. I'm on Node v15.13.0

WilixLead commented 3 years ago

@Durss What the errors you get? Also, please review this PR https://github.com/wilix-team/iohook/pull/294 - it drop Node 8/9 supporting but previous versions of iohook can still work.

ash0x0 commented 3 years ago

Is this still an issue or should I close?

denyncrawford commented 3 years ago

No idea personally I decided to use gkm, although I think iohook would have been a cleaner solution, tomorrow I will try to test with a newer version of node to see if there is anything to report.

sancarn commented 3 years ago

We, at LaunchMenu, too had this issue with iohook, and after messing around with node-gyp we decided to remake the package ourselves. We've created a package named node-global-key-listener. The application uses native low level hooks and pre-compiled binaries instead of relying on node-gyp or any other pre-installed dependencies. Currently the package only supports Windows and Mac operating system, but we'd be happy to get Linux support from someone in the know :) The package has gone through a short testing phase and is showing promise. You can read more about limitations in our readme. Hope it helps you out 👍

ash0x0 commented 3 years ago

@sancarn Your contributions to this project are more than welcome of course. I think your project offers a unique take and would probably have less problems, especially for Mac I imagine. I would say though there are no fundamental issues with node-gyp other than not wanting to increase your dependencies. It's better than relying on spawning directly. You may want to use a more concrete solution or use node C++ addon for the windows implementation instead of spawning. Also, you can take a look at libuiohook for linux implementation, it's C so if you don't want to add it as dependency you can use just the x11 implementation in your project. It has its limitations of course but it would make the project usable cross-platform.

sancarn commented 3 years ago

I would say though there are no fundamental issues with node-gyp other than not wanting to increase your dependencies.

Over the years I've used numerous packages which have used gyp, and they have always caused a nightmare whether it be in production or in development. Generally I tend to avoid gyp packages wherever I can because of the negative experience I've had with gyp. But you're right, there probably isn't any real problem with gyp especially if you know what you're doing :)

Thanks for libuiohook's implementation :) Will look into it. 👍

miro-ux commented 3 years ago

Any possible fix or update related to this issue, without downgrading node?

@denyncrawford I was able to get this functional on node v14 by using v0.6.6 of the library. It seems that versions past that (0.7.x) are broken.

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ npm add iohook@0.7.0

[removed adding logging]

+ iohook@0.7.0

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ node index.js
refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).
[exits with no message]

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ npm remove iohook

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ npm remove iohook && npm add iohook@0.6.6

[removed removal & adding logging]

removed 148 packages and audited 10 packages in 1.031s
+ iohook@0.6.6

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ node index.js
refresh_locale_list [476]: GetKeyboardLayoutList(0, NULL) found 3 layouts.
refresh_locale_list [493]: Received 3 locales.
load_input_helper [866]: refresh_locale_list() found 3 locale(s).
Connected to device!
Data received

gongo@Gonputer MINGW64 ~/workplace/tuya/test
$ node -v
v14.0.0

Can't get it to work with 0.6.6.

I get: Prebuild for current platform (iohook-v0.6.6-electron-v87-win32-x64) not found!

With Node v14 and electron v12, my package.json looks like this:


  "devDependencies": {
    "electron": "^12.0.11",
    "electron-packager": "^15.2.0"
  },
  "dependencies": {
    "cmake-js": "^6.1.0",
    "iohook": "^0.6.6",
    "node-abi": "^2.30.0"
  },
  "iohook": {
    "targets": [
      "electron-87",
      "node-83"
    ],
    "platforms": [
      "win32"
    ],
    "arches": [
      "x64"
    ]
  }

Any idea what I'm doing wrong?

marcelblum commented 3 years ago

@miro-ux this thread is about an issue using iohook in just-plain-Node not Electron. Since you're using Electron, latest iohook 0.9.3 works fine in Electron 12 on Windows. iohook 0.6.6 predates Electron 12 so there is no older 0.6.6 prebuild targeting Electron 12.

miro-ux commented 3 years ago

@marcelblum You're right. Seems to be working great now with 0.9.3 and Electron 12. I was banging my head all day trying to make it work for Electron 13 or 14-beta. Thanks a lot!

kybarg commented 2 years ago

@TheMrGong thank you os much! 0.6.6 works with node 14

AgainPsychoX commented 2 years ago

Any update on making new versions work with Node 14+?