I have had the same problem trying to add a hook to nox player (android emulator). I have tried the same code with another emulator and it works perfectly.
After this, i'm sure that nox includes a anti hook system ... probably same for your program. Nox looks freeze or exits after SetWindowsHookExA and not events captured at all.
EDITED. I know why after some hours checking.... 64 bits app needs 64 bits dlls, and 32 bits apps need 32 bits dlls.
from: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa
SetWindowsHookEx can be used to inject a DLL into another process. A
32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL
cannot be injected into a 32-bit process. If an application requires
the use of hooks in other processes, it is required that a 32-bit
application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit
processes, and a 64-bit application call SetWindowsHookEx to inject a
64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have
different names.
Because hooks run in the context of an application, they must match
the "bitness" of the application. If a 32-bit application installs a
global hook on 64-bit Windows, the 32-bit hook is injected into each
32-bit process (the usual security boundaries apply). In a 64-bit
process, the threads are still marked as "hooked." However, because a
32-bit application must run the hook code, the system executes the
hook in the hooking app's context; specifically, on the thread that
called SetWindowsHookEx. This means that the hooking application must
continue to pump messages or it might block the normal functioning of
the 64-bit processes. If a 64-bit application installs a global hook
on 64-bit Windows, the 64-bit hook is injected into each 64-bit
process, while all 32-bit processes use a callback to the hooking
application.
To hook all applications on the desktop of a 64-bit Windows
installation, install a 32-bit global hook and a 64-bit global hook,
each from appropriate processes, and be sure to keep pumping messages
in the hooking application to avoid blocking normal functioning. If
you already have a 32-bit global hooking application and it doesn't
need to run in each application's context, you may not need to create
a 64-bit version.
https://docs.microsoft.com/en-us/windows/win32/winprog64/process-interoperability
You can run Win32-based applications on 64-bit Windows using an
emulation layer. Windows 10 on ARM includes an x86-on-ARM64 emulation
layer. For more information, see Running 32-bit Applications.
On 64-bit Windows, a 64-bit process cannot load a 32-bit dynamic-link
library (DLL). Additionally, a 32-bit process cannot load a 64-bit
DLL. However, 64-bit Windows supports remote procedure calls (RPC)
between 64-bit and 32-bit processes (both on the same computer and
across computers). On 64-bit Windows, an out-of-process 32-bit COM
server can communicate with a 64-bit client, and an out-of-process
64-bit COM server can communicate with a 32-bit client. Therefore, if
you have a 32-bit DLL that is not COM-aware, you can wrap it in an
out-of-process COM server and use COM to marshal calls to and from a
64-bit process.
cout, that might explain the crash. At any rate, there doesn't seem to be anything wrong with the code as posted, so perhaps the problem is with the code that calls install(), please post the entire program. - Harry Johnston