我正在开发一个窗口应用程序c#.net。该应用程序用于连接其他计算机(窗口计算机)与远程桌面连接,并监视用户在该远程计算机上执行的操作。
为了监视用户操作,我在连接到远程计算机时使用SetWindowsHookEx()方法将WH_KEYBOARD_LL和WH_MOUSE_LL挂钩的自定义挂钩过程安装为全局挂钩过程。
当用户从远程计算机注销时,我需要使用UnhookWindowsHookEx()释放挂钩程序。 问题出现在这里通过显示消息:“フックハンドルが无效です”(这意味着无效的钩子句柄)。
此错误不会始终发生。它有时发生。
我是c#.net开发的初学者。我不知道这个错误。
所以,我想知道为什么在调用UnhookWindowsHookEx()时会发生错误。
拜托,有人帮助我。
我的代码是:
try
{
HookManager.KeyDown -= HookManager_KeyDown;
HookManager.KeyUp -= HookManager_KeyUp;
HookManager.MouseUp -= HookManager_MouseUp;
}
catch (Exception ex)
{
// error is written to log file if uninstalling hook procedure is failed
LogController.Instance.Fatal(ex.Source + CommonConstants.TAB + ex.Message);
}
.....
以上代码执行以下代码:
public static partial class HookManager
{
private static int s_KeyboardHookHandle;
private static event KeyEventHandler s_KeyDown;
public static event KeyEventHandler KeyDown
{
add
{
EnsureSubscribedToGlobalKeyboardEvents();
s_KeyDown += value;
}
remove
{
s_KeyDown -= value;
TryUnsubscribeFromGlobalKeyboardEvents();
}
}
private static void EnsureSubscribedToGlobalKeyboardEvents()
{
// install Keyboard hook only if it is not installed and must be installed
if (s_KeyboardHookHandle == 0)
{
//See comment of this field. To avoid GC to clean it up.
s_KeyboardDelegate = KeyboardHookProc;
//install hook
s_KeyboardHookHandle = SetWindowsHookEx(
WH_KEYBOARD_LL,
s_KeyboardDelegate,
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[0]),
0);
//If SetWindowsHookEx fails.
if (s_KeyboardHookHandle == 0)
{
//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set.
int errorCode = Marshal.GetLastWin32Error();
//do cleanup
//Initializes and throws a new instance of the Win32Exception class with the specified error.
throw new Win32Exception(errorCode);
}
}
}
private static void TryUnsubscribeFromGlobalKeyboardEvents()
{
//if no subsribers are registered unsubsribe from hook
if (s_KeyDown == null &&
s_KeyUp == null &&
s_KeyPress == null)
{
ForceUnsunscribeFromGlobalKeyboardEvents();
}
}
private static void ForceUnsunscribeFromGlobalKeyboardEvents()
{
if (s_KeyboardHookHandle != 0)
{
//uninstall hook
int result = UnhookWindowsHookEx(s_KeyboardHookHandle);
//reset invalid handle
s_KeyboardHookHandle = 0;
//Free up for GC
s_KeyboardDelegate = null;
//if failed and exception must be thrown
if (result == 0)
{
//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set.
int errorCode = Marshal.GetLastWin32Error();
//Initializes and throws a new instance of the Win32Exception class with the specified error.
throw new Win32Exception(errorCode);
}
}
}
private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
//indicates if any of underlaing events set e.Handled flag
bool handled = false;
if (nCode >= 0)
{
//read structure KeyboardHookStruct at lParam
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
//raise KeyDown
if (s_KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
Keys keyData = (Keys)MyKeyboardHookStruct.VirtualKeyCode;
KeyEventArgs e = new KeyEventArgs(keyData);
s_KeyDown.Invoke(null, e);
handled = e.Handled;
}
// raise KeyPress
if (s_KeyPress != null && wParam == WM_KEYDOWN)
{
bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.VirtualKeyCode,
MyKeyboardHookStruct.ScanCode,
keyState,
inBuffer,
MyKeyboardHookStruct.Flags) == 1)
{
char key = (char)inBuffer[0];
if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);
KeyPressEventArgs e = new KeyPressEventArgs(key);
s_KeyPress.Invoke(null, e);
handled = handled || e.Handled;
}
}
// raise KeyUp
if (s_KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
{
Keys keyData = (Keys)MyKeyboardHookStruct.VirtualKeyCode;
KeyEventArgs e = new KeyEventArgs(keyData);
s_KeyUp.Invoke(null, e);
handled = handled || e.Handled;
}
}
//if event handled in application do not handoff to other listeners
if (handled)
return -1;
//forward to other application
return CallNextHookEx(s_KeyboardHookHandle, nCode, wParam, lParam);
}