Search code examples
c#setwindowshookex

Retrieve process- or thread-id of global keypress using SetWindowsHookEx


I've got a specific application which I can find using

Process.GetProcesses()

and filtering by ProcessName. I'd like to filter out all keypress-events of that process, unfortunately one can only pass a optional thread-id to SetWindowsHookEx as last parameter.

That's why I thought about filtering the incoming events but I can't find a way to retrieve the information where it came from. Is there any solution to do it?

The callback-information are provided within LowLevelKeyboardProc having another struct inside lparam: KBDLLHOOKSTRUCT


Solution

  • public partial class Form1 : Form 
    {
        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();
    
        [DllImport("user32.dll")]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
    
        Process process;
    
        public Form1() 
        {
            process = Process.GetProcesses()
                .Where(x => x.ProcessName == "MyProcessName")
                .FirstOrDefault();
    
            //init global keypress as needed
        }
    
        void gkh_KeyUp(object sender, KeyEventArgs e)
        {
            IntPtr handle = GetForegroundWindow();
            uint processID = GetWindowThreadProcessId(handle, IntPtr.Zero);
            if (p2.Threads.OfType<ProcessThread>().Any(x => x.Id == Convert.ToInt32(processID)))
            {
                //keypress in MyProcessName
            }
            e.Handled = true;
        }