C#전역 키보드 스니핑(Hook) 사용
16870 단어 C# - 글로벌 키보드 스니퍼c#글로벌 키보드 스니퍼
어떤 상황에서 응용 프로그램은 단축키가 특정한 기능을 수행해야 한다. 예를 들어 모두가 알고 있는 QQ 캡처 기능인 Ctrl+Alt+A 단축키는 QQ 프로그램이 실행 중이면(초점이 있든 백엔드가 실행 중이든) 단축키를 눌러서 사용할 수 있다.
이때 프로그램에 키보드 감청을 추가하면 수요를 충족시키지 못할 것이다. 사용자가 앱에 초점을 맞추지 않을 때(예를 들어 최소화하거나 사용자가 다른 사물을 처리하는 등) 키보드 감청은 효력을 상실한다.
둘.어떻게 해야만 전역 키보드 감청을 실현할 수 있습니까?
Windows API를 사용하려면 다음과 같은 소스가 필요합니다. (도구 클래스 [KeyboardHook.cs]로 저장할 수 있습니다.)
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;
namespace
{
///
///
/// [ , ]
///
class KeyboardHook
{
public event KeyEventHandler KeyDownEvent;
public event KeyPressEventHandler KeyPressEvent;
public event KeyEventHandler KeyUpEvent;
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
static int hKeyboardHook = 0; //
// Microsoft SDK Winuser.h
// http://www.bianceng.cn/Programming/csharp/201410/45484.htm
public const int WH_KEYBOARD_LL = 13; // 2, 13
HookProc KeyboardHookProcedure; // KeyboardHookProcedure HookProc
//
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode; // 。 1 254
public int scanCode; //
public int flags; //
public int time; //
public int dwExtraInfo; //
}
// ,
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
// ,
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
// ( )
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
// WINDOWS API ,
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
public void Start()
{
//
if (hKeyboardHook == 0)
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
//hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
//************************************
//
//SetWindowsHookEx( 2,KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId());// idGetCurrentThreadId(),
// , (using System.Reflection;)
//SetWindowsHookEx( 13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
//
// SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId) , :
//idHook , , 2, , 13,
// 7, 14。lpfn 。 dwThreadId 0
// ,lpfn DLL 。 ,lpfn 。 ,
// 。hInstance 。 lpfn DLL。 threadId ,
// ,hInstance NULL。 。threaded
// 0, ,
//************************************
// SetWindowsHookEx
if (hKeyboardHook == 0)
{
Stop();
throw new Exception(" ");
}
}
}
public void Stop()
{
bool retKeyboard = true;
if (hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
if (!(retKeyboard)) throw new Exception(" !");
}
//ToAscii
[DllImport("user32")]
public static extern int ToAscii(int uVirtKey, //[in] 。
int uScanCode, // [in] 。 , ( )
byte[] lpbKeyState, // [in] , 256 , 。 ( ) 。 , ( )。 , , 。 , CAPS LOCK 。 NUM 。
byte[] lpwTransKey, // [out] 。
int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.
//
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey);
private const int WM_KEYDOWN = 0x100;//KEYDOWN
private const int WM_KEYUP = 0x101;//KEYUP
private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
private const int WM_SYSKEYUP = 0x105;//SYSKEYUP
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
//
if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null))
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// raise KeyDown
if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyDownEvent(this, e);
}
//
if (KeyPressEvent != null && wParam == WM_KEYDOWN)
{
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
{
KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
KeyPressEvent(this, e);
}
}
//
if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyUpEvent(this, e);
}
}
// 1, , , 。
// 0 CallNextHookEx ,
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
~KeyboardHook()
{
Stop();
}
}
}
셋.위의 도구류를 어떻게 사용합니까?
//0.준비 작업//위의 도구 클래스를 프로젝트에 추가
//1.먼저 필요한 네임스페이스 using System을 가져옵니다.Runtime.InteropServices;//WINDOWS API 함수를 호출할 때 using Microsoft를 사용합니다.Win32;//레지스트리에 쓸 때
//2.훅을 설치하고 프로그램 입구에 아래 코드를 적으세요(본 예에서 WinForm을 사용했고Form의 구조 방법에 훅을 설치하면 됩니다)//키보드 갈고리k 설치hook = new KeyboardHook(); k_hook.KeyDownEvent += new KeyEventHandler(hook_KeyDown);//훅 키 누르기 khook.Start();//키보드 갈고리를 설치하다
//3.키 값 입력(KeyDown 이벤트 구현) private void hook 판단KeyDown(object sender, Key EventArgse) {//누르는 키를 판단하기(Alt + A)if(e.Key Value = (int) Keys.A & & & (int) Control.Modifier Keys = (int) Keys.Alt) {System.Windows.Forms.MessageBox.Show(지정된 단축키 조합을 눌렀음)}//몇 가지 다른 키 값 판단에 주의하십시오://1>.단일 일반 키(예: A)//2>.단일 제어 키 + 단일 일반 키(예: Ctrl+A)//3>.다중 제어 키 + 단일 일반 키 (예: Ctrl + Alt + A)//위의 코드에서 2 를 보여 주었는데, 다른 상황은 이것으로 미루어 보면, 단지 몇 가지 조건을 더 넣고 다시 & 일어나면 된다
넷.전역 키보드를 사용하여 주의해야 할 문제를 감청합니다. (독자분들은 꼭 보십시오.)
1. 응용 프로그램에서 전역 키보드를 사용하여 감청하면 360에 발견되며, 탄창은 사용자에게 "키보드 입력을 감청하는 프로그램이 있는데 막으시겠습니까?"라고 알린다.
그래서 만약에 프로그램에서 Hook을 사용해야 한다면 사용자에게 정보를 누설하지 말라고 알려줘야 돼요.
아니면 그냥 App을 360 심사에 제출하세요.
그렇지 않으면 약하다는 힌트는 사용자 체험에 지대한 영향을 끼칠 수 있다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
c# Aspose를 사용하여 파일을 인쇄하는 예최근 winform 인쇄 파일을 연구하려면 워드, excel, ppt, pdf, 그림 등 몇 가지 형식을 지원해야 하기 때문에 관련 소프트웨어 환경에 의존할 수 없습니다. 연구 후 Aspose 세트로 관련 파일을 모...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.