-1

I'm trying to install either a WH_KEYBOARD_LL or WH_MOUSE_LL hook into a certain Process/Window.

[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookHandler fn, IntPtr module, uint dwThreadId);

[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);

public bool Install(Process process)
{
    const int WH_KEYBOARD_LL = 0x0D;

    if (instance == IntPtr.Zero)
    {
        var threadId = GetWindowThreadProcessId(process.MainWindowHandle, IntPtr.Zero);

        instance = SetWindowsHookEx(WH_KEYBOARD_LL, handler, IntPtr.Zero, threadId);
    }

    return instance != IntPtr.Zero;
}

Where handler is a reference to my IntPtr Callback(int nCode, IntPtr wParam, IntPtr lParam) callback.

I can successfully hook globaly by replacing the third SetWindowsHookEx argument to a result of the LoadLibrary("User32") call and making threadId 0, like so:

var module = LoadLibrary("User32");

SetWindowsHookEx(WH_KEYBOARD_LL, handler, module, 0u);

How do I get it to work?

Yves Calaci
  • 1,019
  • 1
  • 11
  • 37
  • 2
    https://devblogs.microsoft.com/oldnewthing/20180926-00/?p=99825 Low level keyboard hook is global, you cannot associate it with a thread – Charlieface Feb 13 '21 at 20:58
  • @Charlieface excuse me... So? – Yves Calaci Feb 13 '21 at 21:00
  • 2
    no any injection will be with *_LL* hooks. this is global. pass `threadId` is error, *This hook is called in the context of the thread that installed it.* – RbMm Feb 13 '21 at 21:11
  • See https://stackoverflow.com/questions/1811383/setwindowshookex-in-c-sharp - _I'm trying to hook a 3rd party app so that I can draw to its screen. Drawing to the screen is easy, and I need no help with it, but I seem to be having issues with using SetWindowsHookEx to handle WH_GETMESSAGE. I can't figure out what to pass for the last two parameters._ – stuartd Feb 13 '21 at 21:24
  • @stuartd why would it be a duplication when they are completely different hook types? – Yves Calaci Feb 13 '21 at 21:26
  • @Henri noticed that, edited, content may be helpful – stuartd Feb 13 '21 at 21:26
  • *How do I get it to work?* - what work ? – RbMm Feb 13 '21 at 23:24
  • @RbMm are you sure you read the post? – Yves Calaci Feb 13 '21 at 23:34
  • are you sure that read previous comments ? _LL hooks is global only. it always called in the context of the thread that installed it. it can not be used for inject. so again - what is not work ? – RbMm Feb 13 '21 at 23:35
  • @RbMm the `how do I get it to work` was `stated before any answers`, so I didn't pay attention that low level hooks are global by the time I wrote this post. Isn't that obvious? – Yves Calaci Feb 13 '21 at 23:37
  • what is your problem ? in what is question ? – RbMm Feb 13 '21 at 23:38
  • @RbMm the problem is stated on the first line: I was trying to hook the keyboard/mouse messages within a given window/process, but figured that it's not possible to do so using low level hooks. – Yves Calaci Feb 13 '21 at 23:41
  • if you need hook the all keyboard/mouse messages on current desktop - you not need hook any process. if you want inject to dll to process, control some window, etc - you need another type of hook – RbMm Feb 13 '21 at 23:44
  • Hi, does the answer solve your issue? Please feel free to let me know if you have any issue and also accept it if it does help. – Zeus Mar 05 '21 at 08:37

1 Answers1

2

You can't.

As documented, a WH_KEYBOARD_LL can be installed as a global hook only. Both low-level keyboard and mouse hooks are executed long before the eventual input receiver has been determined.

The diagram posted under When something gets added to a queue, it takes time for it to come out the front of the queue illustrates, when low-level hooks run.

IInspectable
  • 46,945
  • 8
  • 85
  • 181