0

The goal is to have a minimized application, that can respond to keyboard presses.
The keyboard presses will still be able to affect other applications in focus.

The only way I have found to detect keyboard presses within the minimized application,
is to use a low level keyboard hook:

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class InterceptKeys
{
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

    public static void Main()
    {
        _hookID = SetHook(_proc);
        Application.Run();
        UnhookWindowsHookEx(_hookID);
    }

    private static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                GetModuleHandle(curModule.ModuleName), 0);
        }
    }

    private delegate IntPtr LowLevelKeyboardProc(
        int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook,
        LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
        IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
}

This works, but it prevents the key presses from having any effect on other windows in focus. I want the minimzied application to listen to these keyboard presses, but not have the hook be the only program who knows about the key press.

How can I listen for keyboard events, while still allowing other applications to see these keyboard events?

I thought there might be setting to allow LowLevelKeyboardProc to do this, but I have not found any.

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • So you want to write a keylogger ? – Inept Adept Mar 14 '16 at 14:29
  • Well I can see by the code that you are writting a keylogger as you are following this tutorial http://null-byte.wonderhowto.com/how-to/create-simple-hidden-console-keylogger-c-sharp-0132757/ – Inept Adept Mar 14 '16 at 14:32
  • Have you tried comparing the different seccurity models of windows xp / 7/ 8/ 10 as I think that is where you will find the issue, as that article is 4 years old – Inept Adept Mar 14 '16 at 14:35
  • That set of code is all over the place in hundreds of examples. I just want to make a hotkey, that can toggle an application from being in focus / minimized. Good point. Maybe it's security related. – Trevor Hickey Mar 14 '16 at 14:36
  • I would assume so, as 8 / 10 changed alot of the security scope of each application etc. If you can post win version that you are working against maybe more helpful – Inept Adept Mar 14 '16 at 14:37
  • Windows 7 Professional (SP1) – Trevor Hickey Mar 14 '16 at 14:38
  • Now that is strange as I know through my own experimentation that that code works, are you in a university / or on restricted systems ?? Could be an active directory policy that stops that – Inept Adept Mar 14 '16 at 14:39
  • I'll look into this. We have an antivirus, but I don't believe that is the problem. – Trevor Hickey Mar 14 '16 at 14:43
  • Are you running the application with the administrator token? Also, why not use `RegisterHotKey`, which is the documented and supported way of doing what you seem to be trying to do? You'll still need to be an elevated process if you want this to work as a hotkey in *other* elevated processes, though. – Luaan Mar 14 '16 at 14:53
  • possible duplicate (RegisterHotKey): http://stackoverflow.com/questions/3654787/global-hotkey-in-console-application – DaFi4 Mar 14 '16 at 14:53
  • The command you are most likely looking for is RegisterHotKey not LowLevelKeyboardProc...see above – DaFi4 Mar 14 '16 at 14:56
  • RegisterHotKey looks like what I need. Thanks. – Trevor Hickey Mar 14 '16 at 14:57

0 Answers0