Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#钩住全局键盘事件-.NET4.0_C#_.net_Winforms_Hook - Fatal编程技术网

C#钩住全局键盘事件-.NET4.0

C#钩住全局键盘事件-.NET4.0,c#,.net,winforms,hook,C#,.net,Winforms,Hook,作为我正在开发的媒体播放器应用程序的一部分,我想为媒体控制键(播放、向前跳、向后跳等)钩住全局按键 我已经搜索了大约2个小时,现在试图找到一个解决方案-但我找不到一个有效的。我找到了几个关于同一件事的堆栈溢出答案,但没有一个有效 我尝试了NuGet软件包,但它永远不会触发事件。我也尝试了这个包,但同样的事情发生了,除了控制台上打印的它在启动钩子后立即关闭了钩子——我不知道为什么,甚至在查看了源代码之后 我试图得到这个codeproject项目,但我甚至无法运行演示,两个演示都抛出了我无法跟踪的奇

作为我正在开发的媒体播放器应用程序的一部分,我想为媒体控制键(播放、向前跳、向后跳等)钩住全局按键

我已经搜索了大约2个小时,现在试图找到一个解决方案-但我找不到一个有效的。我找到了几个关于同一件事的堆栈溢出答案,但没有一个有效

我尝试了NuGet软件包,但它永远不会触发事件。我也尝试了这个包,但同样的事情发生了,除了控制台上打印的它在启动钩子后立即关闭了钩子——我不知道为什么,甚至在查看了源代码之后

我试图得到这个codeproject项目,但我甚至无法运行演示,两个演示都抛出了我无法跟踪的奇怪错误


我的问题是,在.NET 4.0中捕获键盘按键的已知工作方式是什么,当我的WinForms应用程序没有被关注时,我可以使用它来捕获键盘按键?

以下是过去X年来我在几个项目中使用的代码。应该可以正常工作(对于Windows上的任何.NET版本)


它可以通过一些代码清理来完成,但我并不介意它的工作。

下面是该类的一个固定版本,它不会给出访问冲突错误:

public class KeyboardHook : IDisposable
{
    bool Global = false;

    public delegate void ErrorEventHandler(Exception e);
    public delegate void LocalKeyEventHandler(Keys key, bool Shift, bool Ctrl, bool Alt);
    public event LocalKeyEventHandler KeyDown;
    public event LocalKeyEventHandler KeyUp;
    public event ErrorEventHandler OnError;

    public delegate int CallbackDelegate(int Code, IntPtr W, IntPtr L);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct KBDLLHookStruct
    {
        public Int32 vkCode;
        public Int32 scanCode;
        public Int32 flags;
        public Int32 time;
        public Int32 dwExtraInfo;
    }

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern IntPtr SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, IntPtr hInstance, int threadId);
    
  
    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern bool UnhookWindowsHookEx(IntPtr idHook);

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern int CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
    private static extern int GetCurrentThreadId();
    
    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    public enum HookType : int
    {
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_HARDWARE = 8,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14
    }

    private IntPtr HookID = IntPtr.Zero;
    CallbackDelegate TheHookCB = null;

    //Start hook
    public KeyboardHook(bool Global)
    {
        this.Global = Global;
        TheHookCB = new CallbackDelegate(KeybHookProc);
        if (Global)
        {
            IntPtr hInstance = LoadLibrary("User32");
            HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
                hInstance, //0 for local hook. or hwnd to user32 for global
                0); //0 for global hook. eller thread for hooken
        }
        else
        {
            HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
                IntPtr.Zero, //0 for local hook. or hwnd to user32 for global
                GetCurrentThreadId()); //0 for global hook. or thread for the hook
        }
    }

    public void test()
    {
        if (OnError != null) OnError(new Exception("test"));
    }
    bool IsFinalized = false;
    ~KeyboardHook()
    {
        if (!IsFinalized)
        {
            UnhookWindowsHookEx(HookID);
            IsFinalized = true;
        }
    }
    public void Dispose()
    {
        if (!IsFinalized)
        {
            UnhookWindowsHookEx(HookID);
            IsFinalized = true;
        }
    }
    [STAThread]
    //The listener that will trigger events
    private int KeybHookProc(int Code, IntPtr W, IntPtr L)
    {
        
        KBDLLHookStruct LS = new KBDLLHookStruct();
        if (Code < 0)
        {
            return CallNextHookEx(HookID, Code, W, L);
        }
        try
        {
            if (!Global)
            {
                if (Code == 3)
                {
                    IntPtr ptr = IntPtr.Zero;

                    int keydownup = L.ToInt32() >> 30;
                    if (keydownup == 0)
                    {
                        if (KeyDown != null) KeyDown((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                    }
                    if (keydownup == -1)
                    {
                        if (KeyUp != null) KeyUp((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                    }
                    //System.Diagnostics.Debug.WriteLine("Down: " + (Keys)W);
                }
            }
            else
            {
                KeyEvents kEvent = (KeyEvents)W;

                Int32 vkCode = Marshal.ReadInt32((IntPtr)L); //Leser vkCode som er de første 32 bits hvor L peker.

                if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown && kEvent != KeyEvents.SKeyUp)
                {
                }
                if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown)
                {
                    if (KeyDown != null) KeyDown((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                }
                if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp)
                {
                    if (KeyUp != null) KeyUp((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                }
            }
        }
        catch (Exception e)
        {
            if (OnError != null) OnError(e);
            //Ignore all errors...
        }

        return CallNextHookEx(HookID, Code, W, L);

    }

    public enum KeyEvents
    {
        KeyDown = 0x0100,
        KeyUp = 0x0101,
        SKeyDown = 0x0104,
        SKeyUp = 0x0105
    }

    [DllImport("user32.dll")]
    static public extern short GetKeyState(System.Windows.Forms.Keys nVirtKey);

    public static bool GetCapslock()
    {
        return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.CapsLock)) & true;
    }
    public static bool GetNumlock()
    {
        return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.NumLock)) & true;
    }
    public static bool GetScrollLock()
    {
        return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.Scroll)) & true;
    }
    public static bool GetShiftPressed()
    {
        int state = GetKeyState(System.Windows.Forms.Keys.ShiftKey);
        if (state > 1 || state < -1) return true;
        return false;
    }
    public static bool GetCtrlPressed()
    {
        int state = GetKeyState(System.Windows.Forms.Keys.ControlKey);
        if (state > 1 || state < -1) return true;
        return false;
    }
    public static bool GetAltPressed()
    {
        int state = GetKeyState(System.Windows.Forms.Keys.Menu);
        if (state > 1 || state < -1) return true;
        return false;
    }
}
公共类键盘挂钩:IDisposable
{
bool-Global=false;
公共委托无效ErrorEventHandler(例外e);
公共委托void LocalKeyEventHandler(键键、bool Shift、bool Ctrl、bool Alt);
公共事件LocalKeyEventHandler KeyDown;
公共事件LocalKeyEventHandler KeyUp;
公共事件ErrorEventHandler OnError;
公共委托int CallbackDelegate(int代码,IntPtr W,IntPtr L);
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
公共结构KBDLLHookStruct
{
公共Int32 vkCode;
公共Int32扫描码;
32面国旗;
公共时间;
公共Int32 dwExtraInfo;
}
[DllImport(“user32”,CallingConvention=CallingConvention.StdCall)]
私有静态外部IntPtr setWindowshookx(HookType-idHook,CallbackDelegate-lpfn,IntPtr-hInstance,int-threadId);
[DllImport(“user32”,CallingConvention=CallingConvention.StdCall)]
私有静态外部bool unhookwindowshookx(IntPtr idHook);
[DllImport(“user32”,CallingConvention=CallingConvention.StdCall)]
私有静态extern int CallNextHookEx(IntPtr idHook、intncode、IntPtr wParam、IntPtr lParam);
[DllImport(“kernel32.dll”,CallingConvention=CallingConvention.StdCall)]
私有静态外部int GetCurrentThreadId();
[DllImport(“kernel32.dll”)]
静态外部IntPtr加载库(字符串lpFileName);
公共枚举类型:int
{
WH_JOURNALRECORD=0,
WH_JOURNALPLAYBACK=1,
WH_键盘=2,
WH_GETMESSAGE=3,
WH_CALLWNDPROC=4,
WH_CBT=5,
WH_SYSMSGFILTER=6,
WH_鼠标=7,
WH_硬件=8,
WH_DEBUG=9,
WH_外壳=10,
WH_FOREGROUNDIDLE=11,
WH_CALLWNDPROCRET=12,
WH_KEYBOARD_LL=13,
WH_鼠标\u LL=14
}
私有IntPtr HookID=IntPtr.Zero;
CallbackDelegate thehookb=null;
//起动钩
公用键盘挂钩(bool全球)
{
这个。全局=全局;
hookcb=新回调委托(KeybHookProc);
国际单项体育联合会(全球)
{
IntPtr hInstance=LoadLibrary(“User32”);
HookID=setWindowshookx(HookType.WH\u KEYBOARD\u LL,hookcb,
hInstance,//0表示本地钩子,hwnd表示全局钩子
0);//0表示全局钩子。eller螺纹表示钩子
}
其他的
{
HookID=setWindowshookx(HookType.WH_键盘,hookcb,
IntPtr.Zero,//0表示本地钩子,或hwnd到user32表示全局钩子
GetCurrentThreadId());//0表示全局钩子。或线程表示钩子
}
}
公开无效测试()
{
如果(OnError!=null)OnError(新异常(“测试”));
}
bool=false;
~KeyboardHook()
{
如果(!IsFinalized)
{
UnhookWindowsHookEx(HookID);
Is=真;
}
}
公共空间处置()
{
如果(!IsFinalized)
{
UnhookWindowsHookEx(HookID);
Is=真;
}
}
[状态线程]
//将触发事件的侦听器
专用int KeybHookProc(int代码,IntPtr W,IntPtr L)
{
KBDLLHookStruct LS=新的KBDLLHookStruct();
如果(代码<0)
{
返回CallNextHookEx(HookID,Code,W,L);
}
尝试
{
如果(!全局)
{
如果(代码==3)
{
IntPtr ptr=IntPtr.0;
int keydownup=L.ToInt32()>>30;
if(keydownup==0)
{
如果(KeyDown!=null)KeyDown((Keys)W,GetShiftPressed(),GetCtrlPressed(),GetAltPressed());
}
if(keydownup==-1)
{
如果(KeyUp!=null)KeyUp((Keys)W,GetShiftPressed(),GetCtrlPressed(),GetAltPressed());
}
//System.Diagnostics.Debug.WriteLine(“向下:”+(键)W);
}
}
其他的
{
KeyEvents kEvent=(KeyEvents)W;
Int32 vkCode=Marshal.ReadInt32((IntPtr)L);//Leser vkCode som er de første 32位hvor L peker。
if(kEvent!=KeyEvents.KeyDown&&kEvent!=KeyEvents.KeyUp&&kEvent!=KeyEvents.SKeyDown&&kEvent!=KeyEvents.SKeyUp)
{
}
if(kEvent==KeyEvents.KeyDown | kEvent==KeyEvents.SKeyDown)
{
如果(KeyDown!=null)KeyDown((Keys)vkCode,GetShiftPressed(),Get
static class Program
{
    [STAThread]
    static void Main()
    {
        var kh = new KeyboardHook(true);
        kh.KeyDown += Kh_KeyDown;
        Application.Run();
    }

    private static void Kh_KeyDown(Keys key, bool Shift, bool Ctrl, bool Alt)
    {
        Debug.WriteLine("The Key: " + key);
    }
}
public class KeyboardHook : IDisposable
{
    bool Global = false;

    public delegate void ErrorEventHandler(Exception e);
    public delegate void LocalKeyEventHandler(Keys key, bool Shift, bool Ctrl, bool Alt);
    public event LocalKeyEventHandler KeyDown;
    public event LocalKeyEventHandler KeyUp;
    public event ErrorEventHandler OnError;

    public delegate int CallbackDelegate(int Code, IntPtr W, IntPtr L);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct KBDLLHookStruct
    {
        public Int32 vkCode;
        public Int32 scanCode;
        public Int32 flags;
        public Int32 time;
        public Int32 dwExtraInfo;
    }

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern IntPtr SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, IntPtr hInstance, int threadId);
    
  
    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern bool UnhookWindowsHookEx(IntPtr idHook);

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern int CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
    private static extern int GetCurrentThreadId();
    
    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    public enum HookType : int
    {
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_HARDWARE = 8,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14
    }

    private IntPtr HookID = IntPtr.Zero;
    CallbackDelegate TheHookCB = null;

    //Start hook
    public KeyboardHook(bool Global)
    {
        this.Global = Global;
        TheHookCB = new CallbackDelegate(KeybHookProc);
        if (Global)
        {
            IntPtr hInstance = LoadLibrary("User32");
            HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
                hInstance, //0 for local hook. or hwnd to user32 for global
                0); //0 for global hook. eller thread for hooken
        }
        else
        {
            HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
                IntPtr.Zero, //0 for local hook. or hwnd to user32 for global
                GetCurrentThreadId()); //0 for global hook. or thread for the hook
        }
    }

    public void test()
    {
        if (OnError != null) OnError(new Exception("test"));
    }
    bool IsFinalized = false;
    ~KeyboardHook()
    {
        if (!IsFinalized)
        {
            UnhookWindowsHookEx(HookID);
            IsFinalized = true;
        }
    }
    public void Dispose()
    {
        if (!IsFinalized)
        {
            UnhookWindowsHookEx(HookID);
            IsFinalized = true;
        }
    }
    [STAThread]
    //The listener that will trigger events
    private int KeybHookProc(int Code, IntPtr W, IntPtr L)
    {
        
        KBDLLHookStruct LS = new KBDLLHookStruct();
        if (Code < 0)
        {
            return CallNextHookEx(HookID, Code, W, L);
        }
        try
        {
            if (!Global)
            {
                if (Code == 3)
                {
                    IntPtr ptr = IntPtr.Zero;

                    int keydownup = L.ToInt32() >> 30;
                    if (keydownup == 0)
                    {
                        if (KeyDown != null) KeyDown((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                    }
                    if (keydownup == -1)
                    {
                        if (KeyUp != null) KeyUp((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                    }
                    //System.Diagnostics.Debug.WriteLine("Down: " + (Keys)W);
                }
            }
            else
            {
                KeyEvents kEvent = (KeyEvents)W;

                Int32 vkCode = Marshal.ReadInt32((IntPtr)L); //Leser vkCode som er de første 32 bits hvor L peker.

                if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown && kEvent != KeyEvents.SKeyUp)
                {
                }
                if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown)
                {
                    if (KeyDown != null) KeyDown((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                }
                if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp)
                {
                    if (KeyUp != null) KeyUp((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
                }
            }
        }
        catch (Exception e)
        {
            if (OnError != null) OnError(e);
            //Ignore all errors...
        }

        return CallNextHookEx(HookID, Code, W, L);

    }

    public enum KeyEvents
    {
        KeyDown = 0x0100,
        KeyUp = 0x0101,
        SKeyDown = 0x0104,
        SKeyUp = 0x0105
    }

    [DllImport("user32.dll")]
    static public extern short GetKeyState(System.Windows.Forms.Keys nVirtKey);

    public static bool GetCapslock()
    {
        return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.CapsLock)) & true;
    }
    public static bool GetNumlock()
    {
        return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.NumLock)) & true;
    }
    public static bool GetScrollLock()
    {
        return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.Scroll)) & true;
    }
    public static bool GetShiftPressed()
    {
        int state = GetKeyState(System.Windows.Forms.Keys.ShiftKey);
        if (state > 1 || state < -1) return true;
        return false;
    }
    public static bool GetCtrlPressed()
    {
        int state = GetKeyState(System.Windows.Forms.Keys.ControlKey);
        if (state > 1 || state < -1) return true;
        return false;
    }
    public static bool GetAltPressed()
    {
        int state = GetKeyState(System.Windows.Forms.Keys.Menu);
        if (state > 1 || state < -1) return true;
        return false;
    }
}