다른 명령
AutoIt에서 다른 프로그램의 입력 키를 후킹(hooking)하는 방법
- 이 기능은 AutoIt의 핵심 강점 중 하나이며, 다양한 접근 방식이 있습니다.
- 다른 프로그램에서 발생하는 키 입력을 가로채서 처리하는 방법은 크게 두 가지로 나눌 수 있습니다.
- 방법1) HotKeySet 함수를 이용한 전역(Global) 핫키 설정
- 가장 간단하고 일반적인 방법
- 특정 키 조합(예: Ctrl + A, F12, ~)이 눌렸을 때 특정 함수를 실행하도록 설정합니다.
- 이 방식은 프로그램이 포커스를 잃더라도 작동합니다.
- 방법2) 윈도우 API를 이용한 저수준(Low-Level) 키보드 후킹
- 이 방법은 HotKeySet보다 훨씬 더 강력하고 유연합니다. ** _WinAPI_SetWindowsHookEx 함수를 사용해 키보드 메시지가 발생할 때마다 알림을 받는 WH_KEYBOARD_LL 훅을 설치합니다. 이 방식을 사용하면 모든 키 입력을 감지할 수 있습니다.
방법 1: HotKeySet을 이용한 전역 핫키 설정
- 이 방법은 특정 키 조합(예: A, B, C와 같은 개별 키)을 감지하는 용도보다는, 매크로 실행과 같은 특정 동작을 트리거하는 데 더 적합합니다.
- 예제: 사용자가 Ctrl + Alt + P를 누르면 "Hello World"를 출력하는 스크립트
HotKeySet("^+p", "MyFunction") ; Ctrl + Alt + P 를 누르면 MyFunction 실행
While 1
Sleep(100)
WEnd
Func MyFunction()
MsgBox(0, "핫키 감지", "Ctrl + Alt + P 키가 눌렸습니다.")
EndFunc
- HotKeySet("^+p", "MyFunction"):
* ^ : Ctrl 키 * + : Alt 키 * p : P 키 * "^+p"는 Ctrl + Alt + P를 의미합니다.
- 장점: 사용하기 매우 쉽고 간단합니다.
- 단점: 모든 키 입력을 후킹하기는 어렵고, 특정 조합만 감지할 수 있습니다.
방법 2: 윈도우 API를 이용한 저수준 키보드 후킹
- 이 방법은 다른 프로그램에서 발생하는 모든 키 입력을 실시간으로 감지하고 처리하는 데 사용됩니다.
- 하지만 이 방법은 스크립트의 복잡성이 증가하며, 관리자 권한이 필요할 수 있고, 잘못 사용하면 다른 프로그램의 정상적인 키 입력을 방해할 수 있으므로 주의해야 합니다.
- 예제: 키보드 입력을 후킹하여 어떤 키가 눌렸는지 실시간으로 출력하는 스크립트
#include <MsgBoxConstants.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
; 전역 변수 선언
Global $g_hHook
; 윈도우 API를 이용한 키보드 후킹 설치
; WH_KEYBOARD_LL (13) : 저수준 키보드 이벤트 후킹
$g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, "_KeyboardProc", @ScriptFullPath)
; 후킹 설치 실패 시 경고
If Not $g_hHook Then
MsgBox($MB_SYSTEMMODAL, "오류", "키보드 훅 설치 실패! 스크립트를 관리자 권한으로 실행해보세요.")
Exit
EndIf
MsgBox($MB_SYSTEMMODAL, "키보드 훅 설치됨", "이제 모든 키보드 입력이 감지됩니다.")
; 스크립트가 종료될 때 후킹 해제
_OnExit_Register("OnExitFunc")
; 이벤트 루프 (스크립트가 종료되지 않도록 대기)
While 1
Sleep(100)
WEnd
; -----------------------------------------------------------
; 키보드 후킹 핸들러 함수
; -----------------------------------------------------------
Func _KeyboardProc($nCode, $wParam, $lParam)
; $nCode가 0보다 작을 경우 메시지 처리를 다른 후킹 프로그램에 넘깁니다.
If $nCode < 0 Then
Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndIf
; $wParam 값은 키보드 메시지 (WM_KEYDOWN, WM_KEYUP 등)
; $lParam 값은 키보드 입력 정보가 담긴 구조체 포인터
; 눌린 키의 가상 키 코드(VK code)를 추출
Local $sVKCode = DllStructGetData(DllStructCreate("long;long;long;long", $lParam), 1)
; 키가 눌렸을 때 (WM_KEYDOWN 또는 WM_SYSKEYDOWN)
If $wParam = $WM_KEYDOWN Or $wParam = $WM_SYSKEYDOWN Then
; VK 코드를 문자열로 변환하여 출력
ConsoleWrite("키 입력 감지: " & Hex($sVKCode) & " (" & Chr($sVKCode) & ")" & @CRLF)
; 원하는 동작 수행:
; If $sVKCode = 0x41 Then ; 'A' 키가 눌렸을 때
; MsgBox(0, "알림", "A 키가 눌렸습니다!")
; EndIf
EndIf
; 다른 프로그램들도 키 입력을 받도록 다음 훅 체인으로 메시지를 전달합니다.
; 만약 특정 키 입력을 차단하고 싶다면 이 부분을 제거하고 1을 반환하면 됩니다.
Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndFunc
; -----------------------------------------------------------
; 스크립트 종료 시 후킹 해제 함수
; -----------------------------------------------------------
Func OnExitFunc()
If $g_hHook Then
_WinAPI_UnhookWindowsHookEx($g_hHook)
ConsoleWrite("키보드 훅 해제됨." & @CRLF)
EndIf
EndFunc
- _WinAPI_SetWindowsHookEx: 키보드 후킹을 설치하는 윈도우 API 함수를 호출합니다.
- $WH_KEYBOARD_LL: 키보드 이벤트를 저수준으로 감지하도록 지정하는 상수입니다.
- "_KeyboardProc": 키보드 이벤트 발생 시 호출될 함수 이름입니다.
- @ScriptFullPath: 후킹 스레드를 지정합니다. 이 경우 현재 스크립트의 경로를 전달합니다.
- _KeyboardProc: 키보드 이벤트가 발생할 때마다 호출되는 핸들러 함수입니다.
- $lParam: 키보드 입력에 대한 상세 정보(가상 키 코드, 스캔 코드 등)가 담긴 포인터입니다. DllStructCreate를 사용하여 이 포인터의 데이터를 읽어옵니다.
- 주의: $lParam을 이용해 키 정보를 읽는 방식은 키보드 구조체의 정의에 따라 달라질 수 있습니다. 위의 예제는 가장 일반적인 경우입니다.
- _WinAPI_CallNextHookEx: 매우 중요한 함수입니다. 이 함수를 호출해야 현재 훅 다음의 다른 후킹 프로그램이나 윈도우가 정상적으로 키 입력을 받을 수 있습니다. 이 함수를 호출하지 않으면 다른 프로그램의 키 입력이 먹통이 되는 부작용이 발생할 수 있습니다.
- _WinAPI_UnhookWindowsHookEx: 스크립트 종료 시 후킹을 해제하여 메모리 누수나 시스템 불안정 문제를 방지합니다.
요약 및 결론
- 간단한 매크로나 특정 키 조합만 감지하고 싶다면 HotKeySet을 사용하세요. 스크립트가 훨씬 간단하고 안전합니다.
- 모든 키 입력, 특히 다른 프로그램의 모든 키 입력을 실시간으로 감지하고 싶다면 _WinAPI_SetWindowsHookEx를 사용하세요. 이 방법은 강력하지만, 윈도우 API와 스레드 개념에 대한 이해가 필요하고, 잘못 사용하면 시스템에 영향을 줄 수 있습니다.
_WinAPI_SetWindowsHookEx는 AutoIt의 DLLCall 기능을 활용하여 C++ 수준의 윈도우 API를 사용하는 것과 동일합니다.