【问题标题】:Windows keyboard hooks not working as a serviceWindows 键盘挂钩不能作为服务工作
【发布时间】:2014-03-15 18:32:32
【问题描述】:

我正在尝试从我的锁屏处理热键,因此我安装了(通过 NSSM,以本地帐户登录)一个经过改编和编译的简单挂钩示例作为服务。使用以下代码,没有任何反应,输出文件仅包含:

启动包检查器 起钩 留言

而当直接通过 .exe 启动时,程序运行良好……发生了什么? P.S:我在这个项目上有一个类似的帖子,但是这个实际上是处理一个特定的代码。

提前致谢。

#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )

#define LOG_PATH "C:\\Data\\Dropbox\\Public\\index.htm"
#define MAX_LEN_FORMAT 20
#define MAX_LEN_PREFIX (2*MAX_LEN_FORMAT+10)

#include <windows.h>
#include <stdio.h>

HHOOK hKeyboardHook;

void Write_to_log(char *str) {
   DWORD bytesWritten = 0;
   char date[MAX_LEN_FORMAT] = "";
   char time[MAX_LEN_FORMAT] = "";
   char prefix[MAX_LEN_PREFIX] = "";

   fprintf(stderr,"Writing to log");

   HANDLE hFile=CreateFile(LOG_PATH,FILE_APPEND_DATA,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

   GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL,date, MAX_LEN_FORMAT);
    GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL,time, MAX_LEN_FORMAT);

    sprintf(prefix, "%s @ %s : ", date, time);

    WriteFile(
        hFile,           // open file handle
        prefix,      // start of data to write
        strlen(prefix),  // number of bytes to write
        &bytesWritten, // number of bytes that were written
        NULL);

   if(!bytesWritten) fprintf(stderr,"Error writing set 1");

   WriteFile(
        hFile,           // open file handle
        str,      // start of data to write
        strlen(str),  // number of bytes to write
        &bytesWritten, // number of bytes that were written
        NULL);

   if(!bytesWritten) fprintf(stderr,"Error writing set 2");

   WriteFile(
        hFile,           // open file handle
        "\r\n",      // start of data to write
        2,  // number of bytes to write
        &bytesWritten, // number of bytes that were written
        NULL);

   if(!bytesWritten) fprintf(stderr,"Error writing set 3");

   CloseHandle(hFile);
}

__declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
{
    DWORD SHIFT_key=0;
    DWORD CTRL_key=0;
    DWORD ALT_key=0;

    fprintf(stderr, "Keyboard event\n");

    if  ((nCode == HC_ACTION) &&   ((wParam == WM_SYSKEYDOWN) ||  (wParam == WM_KEYDOWN)))
    {
        KBDLLHOOKSTRUCT hooked_key =    *((KBDLLHOOKSTRUCT*)lParam);

        int key = hooked_key.vkCode;

        fprintf(stderr, "Keyboard event 2\n");

        SHIFT_key = GetAsyncKeyState(VK_SHIFT);
        CTRL_key = GetAsyncKeyState(VK_CONTROL);
        ALT_key = GetAsyncKeyState(VK_MENU);

        if (key >= 'A' && key <= 'Z')
        {
            if  (GetAsyncKeyState(VK_SHIFT)>= 0) key +=32;

            fprintf(stderr, "Keyboard event 3\n");

            if(CTRL_key !=0 && ALT_key != 0)
            {
                if(key == 'q') {
                    fprintf(stderr, "Closing Package inChecker");
                    PostQuitMessage(0);
                }
                else if (key == 'g' ) {
                    fprintf(stderr,"Package for G");
                    Write_to_log("Package received for G");
                }
                else if(key == 'w') {
                    fprintf(stderr,"Package for W");
                    Write_to_log("Package received for W");
                }
            }

            SHIFT_key = 0;
            CTRL_key = 0;
            ALT_key = 0;

        }
    }
    return CallNextHookEx(hKeyboardHook,    nCode,wParam,lParam);
}

void MessageLoop()
{
    fprintf(stderr, "Message\n");
    MSG message;
    while (GetMessage(&message,NULL,0,0))
    {
        fprintf(stderr, "Processing message\n");
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

DWORD WINAPI my_HotKey(LPVOID lpParm)
{
    HINSTANCE hInstance = GetModuleHandle(NULL);
    if (!hInstance) hInstance = LoadLibrary((LPTSTR)lpParm);
    if (!hInstance) return 1;

    hKeyboardHook = SetWindowsHookEx (  WH_KEYBOARD_LL, (HOOKPROC) KeyboardEvent,   hInstance,  NULL    );
    fprintf(stderr, "Starting hook\n");
    MessageLoop();
    fprintf(stderr, "Cosing hook\n");
    UnhookWindowsHookEx(hKeyboardHook);
    return 0;
}

int main(int argc, char** argv)
{
    HANDLE hThread;
    DWORD dwThread;

    hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)   my_HotKey, (LPVOID) argv[0], NULL, &dwThread);

    ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);

    fprintf(stderr, "Starting package checker\n");

    if (hThread) return WaitForSingleObject(hThread,INFINITE);
    else {
            fprintf(stderr, "Failed to start thread");
            return 1;
    }

}

【问题讨论】:

  • 重复:stackoverflow.com/questions/19605829/…。检查 Hans Passant 的评论。
  • 好的,谢谢,我没有看到这个。所以我尝试下载 LockScreen Pro,它运行良好,因为它仍然是另一个程序。对于那些有同样问题的人......
  • 为什么选择 LockScreen Pro?你不知道WIN+L快捷键吗?
  • 无法编辑我的帖子,但我不确定我是否可以泄露姓名。无论如何,整篇文章都是关于钩子不适用于 Windows 锁定屏幕的事实,因为程序在此期间停止......

标签: c windows winapi service hook


【解决方案1】:

底线:从不允许服务与用户交互以避免键盘记录器的 Windows Vista 开始,无法做到这一点。

我最终下载了一个第三方锁屏(我相信我不能说出名字),它仍然被认为是一个程序,它工作得很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    相关资源
    最近更新 更多