2014-02-16 49 views
0

我想從我的鎖屏上處理熱鍵,因此我已經安裝了(通過NSSM,以本地帳戶登錄)一個經過改造和編譯的簡單鉤子示例作爲服務。用下面的代碼,沒有任何反應和輸出文件只包含:Windows鍵盤掛鉤不能用作服務

啓動軟件包檢查 起鉤 消息

時通過該程序正常工作中的.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; 
    } 

} 
+1

Duplicate:http://stackoverflow.com/questions/19605829/can-we-call-setwindowshookex-from-windows-service。檢查Hans Passant評論。 – user2120666

+0

好的,謝謝,我沒有看到這個。所以我嘗試下載LockScreen Pro,它的工作非常漂亮,因爲它仍然是另一個程序。對於那些有同樣問題的人... –

+0

爲什麼LockScreen Pro?你不知道WIN + L的快捷方式? – user2120666

回答

0

底線:從Windows Vista開始,服務不允許與用戶交互以避免鍵盤記錄程序。

我結束了下載第三方鎖屏(我相信我不能說這個名字),它仍然被視爲一個程序,它工作得很好。