如何使跨进程一个键盘钩子全球 [英] How to make a keyboard hook global across processes

查看:155
本文介绍了如何使跨进程一个键盘钩子全球的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个实用的按键程序,所以我可以做的事情一样杀了preprogrammed过程中或启动的东西。我想我应该持有任何应用CMD,然后输入一个4位数的命令键,以便我可以启动或迅速杀死任何东西,而编程,调试观看视频等。

我想出如何获得键盘的回调,但是由于各种原因,一旦我点击到另一个应用程序,我的击键UTIL没有收到更多的键。即使我点击回到我的控制台窗口或MSVC,我将不会收到任何输入。这是除非其全球,让我怎么设置挂钩,是全球性的?

我的code是

  INT的main()
{
    钩=调用SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,的GetModuleHandle(0),0);
    味精味精;
    而(的GetMessage(安培;味精,NULL,0,0)大于0)
    {
        的TranslateMessage(安培;味精);
        在DispatchMessage(安培;味精);
    }
    UnhookWindowsHookEx(钩);
}


解决方案

为了您的键盘钩子可以从所有进程访问,它被放置在随后将被加载到每个进程的地址空间的DLL。要记住一个重要的事情是,由于该DLL的每个实例在一个单独的进程中加载​​,每次都会有自己的DLL中的任何全局变量的副本。如果您需要共享这些实例间的数据,最简单的方法是创建在DLL中的共享数据段。下面code是我写了一个RSI监测方案。

  //
//一些数据会在所有共享
//该DLL的实例
//
的#pragma评论(连接器,/SECTION:.SHARED,RWS)
的#pragma data_seg(共享)
INT iKeyCount = 0;
HHOOK hKeyboardHook = 0;
HHOOK hMouseHook = 0;
的#pragma data_seg()//
//特定实例数据
//
HMODULE的hInstance = 0;//
// DLL加载/卸载入口点
//
BOOL APIENTRY的DllMain(HANDLE HMODULE,
                      DWORD dwReason,
                      LPVOID升preserved)
{
   开关(dwReason)
   {
   案例DLL_PROCESS_ATTACH:
      实例句柄=(HINSTANCE)HMODULE;
      打破;   案例DLL_THREAD_ATTACH:
      打破;   案例DLL_THREAD_DETACH:
      打破;   案例DLL_PROCESS_DETACH:
      打破;
   }
   返回TRUE;
}//
//键盘钩子
//
LRESULT CALLBACK KeyboardProc(INT code,//钩子code
                              WPARAM wParam中,//虚拟键code
                              LPARAM lParam的)//击键消息信息
{
   如果((lParam的&放大器;!为0x80000000)= 0)
   {
      ++ iKeyCount;
   }
   返回CallNextHookEx方法(hKeyboardHook,code,的wParam,lParam的);
}//
//鼠标钩子
//
LRESULT CALLBACK MouseProc(INT code,//钩子code
                           WPARAM wParam中,//消息标识
                           LPARAM lParam的)//鼠标坐标
{
   开关(wParam中)
   {
   案件WM_LBUTTONDOWN:
   案例WM_MBUTTONDOWN:
   案件WM_RBUTTONDOWN:
   案例WM_LBUTTONDBLCLK:
   案例WM_MBUTTONDBLCLK:
   案例WM_RBUTTONDBLCLK:
      ++ iKeyCount;
      打破;
   }
   返回CallNextHookEx方法(hMouseHook,code,的wParam,lParam的);
}//
//安装键盘/鼠标挂钩
//
无效KBM_API InstallHooks(无效)
{
   hKeyboardHook =调用SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,的hInstance,0);
   hMouseHook =调用SetWindowsHookEx(WH_MOUSE,MouseProc,的hInstance,0);
}//
//删除键盘/鼠标挂钩
//
无效KBM_API RemoveHooks(无效)
{
   UnhookWindowsHookEx(hKeyboardHook);
   UnhookWindowsHookEx(hMouseHook);
   hKeyboardHook = hMouseHook = 0;
}//
//检索击键数
//
INT KBM_API FetchKeyCount(布尔bClear)
{
   INT KC = iKeyCount;
   如果(bClear)
      iKeyCount = 0;
   返回KC;
}

I am trying to create a utility keystroke app so i can do things like kill a preprogrammed process or launch something. I am thinking I should hold cmd in any app, then type in a 4 digit command key so I can launch or kill anything quickly while programming, debugging watching a video, etc.

I figured out how to get the keyboard callback, but for whatever reason once I click into another app, my keystroke util receives no more keys. Even if I click back to my console window or msvc, I will not receive any input. This is unless its global, so how do I set the hook to be global?

My code is

int main()
{
    hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle(0), 0);
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    UnhookWindowsHookEx(hook);
}

解决方案

In order for your keyboard hook to be accessible from all processes, it has to be placed in a DLL which will then be loaded into each process' address space. One important thing to keep in mind is that since each instance of the DLL is loaded in a separate process, each will have its own copy of any global variables in the DLL. If you need to share data between these instances, the simplest way is to create a shared data segment in the DLL. The following code is from an RSI monitoring program I wrote.

//
// some data will be shared across all
// instances of the DLL
//
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
int iKeyCount = 0;
HHOOK hKeyboardHook = 0;
HHOOK hMouseHook = 0;
#pragma data_seg()

//
// instance specific data
//
HMODULE hInstance = 0;

//
// DLL load/unload entry point
//
BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  dwReason, 
                      LPVOID lpReserved)
{
   switch (dwReason)
   {
   case DLL_PROCESS_ATTACH :
      hInstance = (HINSTANCE) hModule;
      break;

   case DLL_THREAD_ATTACH :
      break;

   case DLL_THREAD_DETACH :
      break;

   case DLL_PROCESS_DETACH :
      break;
   }
   return TRUE;
}

//
// keyboard hook
//
LRESULT CALLBACK KeyboardProc(int code,       // hook code
                              WPARAM wParam,  // virtual-key code
                              LPARAM lParam)  // keystroke-message information
{
   if ((lParam & 0x80000000) != 0)
   {
      ++iKeyCount;
   }
   return CallNextHookEx(hKeyboardHook, code, wParam, lParam);
}

//
// mouse hook
//
LRESULT CALLBACK MouseProc(int code,       // hook code
                           WPARAM wParam,  // message identifier
                           LPARAM lParam)  // mouse coordinates
{
   switch (wParam)
   {
   case WM_LBUTTONDOWN :
   case WM_MBUTTONDOWN :
   case WM_RBUTTONDOWN :
   case WM_LBUTTONDBLCLK :
   case WM_MBUTTONDBLCLK :
   case WM_RBUTTONDBLCLK :
      ++iKeyCount;
      break;
   }
   return CallNextHookEx(hMouseHook, code, wParam, lParam);
}

//
// install keyboard/mouse hooks
//
void KBM_API InstallHooks(void)
{
   hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0);
   hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hInstance, 0);
}

//
// remove keyboard/mouse hooks
//
void KBM_API RemoveHooks(void)
{
   UnhookWindowsHookEx(hKeyboardHook);
   UnhookWindowsHookEx(hMouseHook);
   hKeyboardHook = hMouseHook = 0;
}

//
// retrieve number of keystrokes
//
int KBM_API FetchKeyCount(bool bClear)
{
   int kc = iKeyCount;
   if (bClear)
      iKeyCount = 0;
   return kc;
}

这篇关于如何使跨进程一个键盘钩子全球的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆