C# 定时器上的低级键盘挂钩

C# 定时器上的低级键盘挂钩,c#,keyboard-hook,C#,Keyboard Hook,我有一个键盘挂钩,可以截取键并输出一个随机字母。我想做的是设置一个计时器,让键盘在一分钟后松开挂钩,然后在另一分钟内重新挂钩。所以,第一部分工作,它在启动时挂起,一分钟后挂起,但再也不会挂起。我怎样才能让它在脱钩后重新上钩 以下是钩子代码: using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.For

我有一个键盘挂钩,可以截取键并输出一个随机字母。我想做的是设置一个计时器,让键盘在一分钟后松开挂钩,然后在另一分钟内重新挂钩。所以,第一部分工作,它在启动时挂起,一分钟后挂起,但再也不会挂起。我怎样才能让它在脱钩后重新上钩

以下是钩子代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Utilities {
/// <summary>
/// A class that manages a global low level keyboard hook
/// </summary>
class globalKeyboardHook {
    #region Constant, Structure and Delegate Definitions
    /// <summary>
    /// defines the callback type for the hook
    /// </summary>
    public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);

    public struct keyboardHookStruct {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    const int WH_KEYBOARD_LL = 13;
    const int WM_KEYDOWN = 0x100;
    const int WM_KEYUP = 0x101;
    const int WM_SYSKEYDOWN = 0x104;
    const int WM_SYSKEYUP = 0x105;

    #endregion

    #region Instance Variables
    /// <summary>
    /// The collections of keys to watch for
    /// </summary>
    public List<Keys> HookedKeys = new List<Keys>();
    /// <summary>
    /// Handle to the hook, need this to unhook and call the next hook
    /// </summary>
    IntPtr hhook = IntPtr.Zero;
    #endregion

    #region Events
    /// <summary>
    /// Occurs when one of the hooked keys is pressed
    /// </summary>
    public event KeyEventHandler KeyDown;
    /// <summary>
    /// Occurs when one of the hooked keys is released
    /// </summary>
    public event KeyEventHandler KeyUp;
    #endregion

    #region Constructors and Destructors
    /// <summary>
    /// Initializes a new instance of the <see cref="globalKeyboardHook"/> class and installs the keyboard hook.
    /// </summary>
    public globalKeyboardHook() {

    }



    /// <summary>
    /// Releases unmanaged resources and performs other cleanup operations before the
    /// <see cref="globalKeyboardHook"/> is reclaimed by garbage collection and uninstalls the keyboard hook.
    /// </summary>
    ~globalKeyboardHook() {
        unhook();
    }
    #endregion

    #region Public Methods
    /// <summary>
    /// Installs the global hook
    /// </summary>
    public void hook() {
        _hookProc = new keyboardHookProc(hookProc);
        IntPtr hInstance = LoadLibrary("User32");
        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
    }

    /// <summary>
    /// Uninstalls the global hook
    /// </summary>
    public void unhook() {
        UnhookWindowsHookEx(hhook);
        hhook = IntPtr.Zero;
    }

    /// <summary>
    /// The callback for the keyboard hook
    /// </summary>
    /// <param name="code">The hook code, if it isn't >= 0, the function shouldn't do anyting</param>
    /// <param name="wParam">The event type</param>
    /// <param name="lParam">The keyhook event information</param>
    /// <returns></returns>
    public int hookProc(int code, int wParam, ref keyboardHookStruct lParam) {
        if (code >= 0) {
            Keys key = (Keys)lParam.vkCode;
            if (HookedKeys.Contains(key)) {
                KeyEventArgs kea = new KeyEventArgs(key);
                if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null)) {
                    KeyDown(this, kea) ;
                } else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null)) {
                    KeyUp(this, kea);
                }
                if (kea.Handled)
                    return 1;
            }
        }
        return CallNextHookEx(hhook, code, wParam, ref lParam);
    }
    #endregion

    #region DLL imports
    /// <summary>
    /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
    /// </summary>
    /// <param name="idHook">The id of the event you want to hook</param>
    /// <param name="callback">The callback.</param>
    /// <param name="hInstance">The handle you want to attach the event to, can be null</param>
    /// <param name="threadId">The thread you want to attach the event to, can be null</param>
    /// <returns>a handle to the desired hook</returns>
    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);

    /// <summary>
    /// Unhooks the windows hook.
    /// </summary>
    /// <param name="hInstance">The hook handle that was returned from SetWindowsHookEx</param>
    /// <returns>True if successful, false otherwise</returns>
    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    /// <summary>
    /// Calls the next hook.
    /// </summary>
    /// <param name="idHook">The hook id</param>
    /// <param name="nCode">The hook code</param>
    /// <param name="wParam">The wparam.</param>
    /// <param name="lParam">The lparam.</param>
    /// <returns></returns>
    [DllImport("user32.dll")]
    static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);

    /// <summary>
    /// Loads the library.
    /// </summary>
    /// <param name="lpFileName">Name of the library</param>
    /// <returns>A handle to the library</returns>
    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    keyboardHookProc _hookProc;

    #endregion
}
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Runtime.InteropServices;
使用System.Windows.Forms;
命名空间实用程序{
/// 
///管理全局低级键盘挂钩的类
/// 
类globalKeyboardHook{
#区域常量、结构和委托定义
/// 
///定义钩子的回调类型
/// 
公共委托int keyboardHookProc(int代码、int wParam、ref keyboardHookStruct lParam);
公共结构keyboardHookStruct{
公共int-vkCode;
公共int扫描码;
公共国旗;
公共整数时间;
公共信息;
}
const int WH_键盘LL=13;
常量int WM_KEYDOWN=0x100;
常量int WM_KEYUP=0x101;
常量int WM_SYSKEYDOWN=0x104;
常量int WM_SYSKEYUP=0x105;
#端区
#区域实例变量
/// 
///要监视的密钥集合
/// 
public List HookedKeys=新列表();
/// 
///钩子的句柄,需要这个来解开钩子并调用下一个钩子
/// 
IntPtr hhook=IntPtr.Zero;
#端区
#地区活动
/// 
///在按下其中一个钩形键时发生
/// 
公共事件KeyEventHandler KeyDown;
/// 
///释放其中一个挂钩键时发生
/// 
公共事件KeyEventHandler KeyUp;
#端区
#区域构造函数和析构函数
/// 
///初始化类的新实例并安装键盘挂钩。
/// 
公共globalKeyboardHook(){
}
/// 
///释放非托管资源并在
///由垃圾回收回收并卸载键盘挂钩。
/// 
~globalKeyboardHook(){
解开钩();
}
#端区
#区域公共方法
/// 
///安装全局钩子
/// 
公共空钩(){
_hookProc=新键盘hookProc(hookProc);
IntPtr hInstance=LoadLibrary(“User32”);
hhook=SetWindowsHookEx(WH_-KEYBOARD,hookProc,hInstance,0);
}
/// 
///卸载全局钩子
/// 
公共空间取消挂钩(){
脱钩(hhook);
hhook=IntPtr.Zero;
}
/// 
///键盘挂钩的回调
/// 
///钩子代码,如果它不是>=0,函数不应该做任何事情
///事件类型
///keyhook事件信息
/// 
public int hookProc(int代码、int wParam、ref keyboardHookStruct lParam){
如果(代码>=0){
Keys key=(Keys)lParam.vkCode;
if(HookedKeys.Contains(键)){
KeyEventArgs kea=新的KeyEventArgs(key);
if((wParam==WM|u KEYDOWN | wParam==WM_SYSKEYDOWN)&&(KEYDOWN!=null)){
KeyDown(这个,kea);
}else if((wParam==WM|u-KEYUP | wParam==WM_-SYSKEYUP)&&(KEYUP!=null)){
KeyUp(这个,kea);
}
如果(千欧处理)
返回1;
}
}
返回CallNextHookEx(hhook、code、wParam、ref lParam);
}
#端区
#区域DLL导入
/// 
///设置windows挂钩,执行所需事件,hInstance或threadId之一必须为非空
/// 
///要挂接的事件的id
///回调。
///要将事件附加到的句柄可以为null
///要将事件附加到的线程可以为null
///所需挂钩的把手
[DllImport(“user32.dll”)]
静态外部IntPtr SETWINDOWSHOOKX(int idHook、keyboardHookProc回调、IntPtr hInstance、uint threadId);
/// 
///打开窗户挂钩。
/// 
///从SetWindowsHookEx返回的钩子句柄
///如果成功,则为True,否则为false
[DllImport(“user32.dll”)]
静态外部bool unhookwindowshookx(IntPtr hInstance);
/// 
///调用下一个钩子。
/// 
///钩子id
///钩子代码
///wparam。
///LPRAM。
/// 
[DllImport(“user32.dll”)]
静态extern int CallNextHookEx(IntPtr idHook、intncode、intwparam、ref keyboardHookStruct lParam);
/// 
///加载库。
/// 
///图书馆名称
///图书馆的把手
[DllImport(“kernel32.dll”)]
静态外部IntPtr加载库(字符串lpFileName);
键盘hookProc\u hookProc;
#端区
}
}
以下是应用程序的入口点:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Utilities;
using System.Timers;

namespace KeyRemapWindowsForm
{
static class Program
{
    static bool _isHookActive = true;
    static globalKeyboardHook gkh  = new globalKeyboardHook();
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        System.Timers.Timer HookTimer = new System.Timers.Timer(60000);
        HookTimer.Elapsed += new ElapsedEventHandler(HookTimer_Elapsed);
        HookTimer.Start();

        Begin();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run();
        GC.KeepAlive(HookTimer);
    }

    // Specify what you want to happen when the Elapsed event is 
    // raised.
    static void HookTimer_Elapsed(object source, ElapsedEventArgs e)
    {
        if (_isHookActive)
        {
            End();
        }
        else
        {
            Begin();
        }
    }

    static void Begin()
    {
        gkh = new globalKeyboardHook();
        gkh.hook();
        gkh.HookedKeys.Add(Keys.A);
        gkh.HookedKeys.Add(Keys.B);
        gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
        gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
        _isHookActive = true;
    }

    static void End()
    {
        gkh.HookedKeys.Clear();
        gkh.KeyDown -= new KeyEventHandler(gkh_KeyDown);
        gkh.KeyUp -= new KeyEventHandler(gkh_KeyUp);
        gkh.unhook();
        _isHookActive = false;
    }

    static void gkh_KeyUp(object sender, KeyEventArgs e)
    {
        SendKeys.Send(((KeyboardKeys)GetRandomKeyCode()).ToString());
        e.Handled = true;
    }

    static void gkh_KeyDown(object sender, KeyEventArgs e)
    {            
        e.Handled = true;
    } 

    static int GetRandomKeyCode()
    {
        int RandomNum = 0;
        while(RandomNum == 0)
        {
            Random RanNum = new Random();
            RandomNum = RanNum.Next(65, 90);

            switch(RandomNum)
            {
                case 68:
                case 69:
                case 86:
                RandomNum = 0;
                    break;
                default:
                    break;
            }

        }

        return RandomNum;
    }
}

public enum KeyboardKeys
{
    /// <summary>
    /// The A key.
    /// </summary>
    A = 65,
    /// <summary>
    /// The B key.
    /// </summary>
    B = 66,
    /// <summary>
    /// The C key.
    /// </summary>
    C = 67,
    /// <summary>
    /// The D key.
    /// </summary>
    D = 68,
    /// <summary>
    /// The E key.
    /// </summary>
    E = 69,
    /// <summary>
    /// The F key.
    /// </summary>
    F = 70,
    /// <summary>
    /// The G key.
    /// </summary>
    G = 71,
    /// <summary>
    /// The H key.
    /// </summary>
    H = 72,
    /// <summary>
    /// The I key.
    /// </summary>
    I = 73,
    /// <summary>
    /// The J key.
    /// </summary>
    J = 74,
    /// <summary>
    /// The K key.
    /// </summary>
    K = 75,
    /// <summary>
    /// The L key.
    /// </summary>
    L = 76,
    /// <summary>
    /// The M key.
    /// </summary>
    M = 77,
    /// <summary>
    /// The N key.
    /// </summary>
    N = 78,
    /// <summary>
    /// The O key.
    /// </summary>
    O = 79,
    /// <summary>
    /// The P key.
    /// </summary>
    P = 80,
    /// <summary>
    /// The Q key.
    /// </summary>
    Q = 81,
    /// <summary>
    /// The R key.
    /// </summary>
    R = 82,
    /// <summary>
    /// The S key.
    /// </summary>
    S = 83,
    /// <summary>
    /// The T key.
    /// </summary>
    T = 84,
    /// <summary>
    /// The U key.
    /// </summary>
    U = 85,
    /// <summary>
    /// The V key.
    /// </summary>
    V = 86,
    /// <summary>
    /// The W key.
    /// </summary>
    W = 87,
    /// <summary>
    /// The X key.
    /// </summary>
    X = 88,
    /// <summary>
    /// The Y key.
    /// </summary>
    Y = 89,
    /// <summary>
    /// The Z key.
    /// </summary>
    Z = 90
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Windows.Forms;
使用公用设施;
使用系统计时器;
命名空间KeyRemapWindowsForm
{
静态类程序
{
静态bool_isHookActive=true;
静态globalKeyboardHook gkh=新的globalKeyboardHook();
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
System.Timers.Timer HookTimer=新的System.Timers.Timer(60000);
HookTimer.appeased+=新的ElapsedEventHandler(HookTimer\u appeased);
HookTimer.Start();
Begin();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run();
GC.KeepAlive(钩子计时器);
}
//指定在运行已过事件时要执行的操作
//提高。
静态void HookTimer_已过(对象源,ElapsedEventArgs e)
{
如果(_isHookActive)
{
End();
}
其他的
{
Begin();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Utilities;
using System.Timers;

namespace KeyRemapWindowsForm
{
static class Program
{
    static bool _isHookActive = true;
    static globalKeyboardHook gkh  = new globalKeyboardHook();

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        System.Timers.Timer HookTimer = new System.Timers.Timer(10000);
        HookTimer.Elapsed += new ElapsedEventHandler(HookTimer_Elapsed);
        HookTimer.Start();

        Application.ApplicationExit += new EventHandler(OnApplicationExit);

        gkh.hook();

        gkh.HookedKeys.Add(Keys.S);
        gkh.HookedKeys.Add(Keys.E);

        gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
        gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run();
        GC.KeepAlive(HookTimer);
    }

    static void OnApplicationExit(object sender, EventArgs e)
    {
        gkh.unhook();
    }

    static void HookTimer_Elapsed(object source, ElapsedEventArgs e)
    {
        if (_isHookActive)
        {
            _isHookActive = false;
        }
        else
        {
            _isHookActive = true;
        }
    }        

    static void gkh_KeyUp(object sender, KeyEventArgs e)
    {
        try
        {
            if (_isHookActive)
            {
                e.Handled = true;
            }
        }
        catch 
        {
            gkh.unhook();
            Application.Exit();
        }
    }

    static void gkh_KeyDown(object sender, KeyEventArgs e)
    {
        try
        {
            if (_isHookActive)
            {
                SendKeys.Send(((Keys)new Random().Next(65, 90)).ToString());
                e.Handled = true;
            }
        }
        catch
        {
            gkh.unhook();
            Application.Exit();
        }
    } 
}
}
this.InvokeCatchDisposedException(new MethodInvoker(() => HookTimer_Elapsed(sender, e)));
            return;