.NET 3.x Исключение при блоке клавиши Win - C#

Узнай цену своей работы

Формулировка задачи:

Вообщем понадобилось мне отключить клавишу Win (в разумных целях), так вот при нажатие первый раз блочит, при повторном, выдает исключение, и всё накрывается разом) Сам класс:
Листинг программы
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Windows.Forms;
  4. using System.Diagnostics;
  5. internal class WinBlock
  6. {
  7. [StructLayout(LayoutKind.Sequential)]
  8. private struct KBDLLHOOKSTRUCT
  9. {
  10. public Keys key;
  11. public int scanCode;
  12. public int flags;
  13. public int time;
  14. public IntPtr extra;
  15. }
  16. private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
  17. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  18. private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
  19. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  20. private static extern bool UnhookWindowsHookEx(IntPtr hook);
  21. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  22. private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
  23. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  24. private static extern IntPtr GetModuleHandle(string name);
  25. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  26. private static extern short GetAsyncKeyState(Keys key);
  27. private IntPtr ptrHook;
  28. private LowLevelKeyboardProc objKeyboardProcess;
  29. private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
  30. {
  31. if (nCode >= 0)
  32. {
  33. KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
  34. if (objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.RWin)
  35. {
  36. return (IntPtr)1;
  37. }
  38. }
  39. return CallNextHookEx(ptrHook, nCode, wp, lp);
  40. }
  41. private delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, IntPtr lParam);
  42. public void SetHook()
  43. {
  44. ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
  45. objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
  46. ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
  47. }
  48. public void Unhook()
  49. {
  50. if (ptrHook != IntPtr.Zero)
  51. {
  52. UnhookWindowsHookEx(ptrHook);
  53. ptrHook = IntPtr.Zero;
  54. }
  55. }
  56. }
Исключение:
Листинг программы
  1. Обнаружено событие CallbackOnCollectedDelegate
  2. Message: Был произведен обратный вызов делегата типа "WinBlock+LowLevelKeyboardProc::Invoke",
  3. полученного сборщиком мусора.
  4. Это может привести к сбоям приложения, а также к повреждению или утрате данных.
  5. При передаче делегатов в неуправляемый код управляемое приложение
  6. должно поддерживать их существование,
  7. пока не будет гарантировано, что они больше никогда не будут вызваны.
Есть ли у кого нибудь рабочий пример: или же как бороться..?

Решение задачи: «.NET 3.x Исключение при блоке клавиши Win»

textual
Листинг программы
  1.         private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             WinBlock.SetHook();
  4.         }
  5.  
  6.         private void button2_Click(object sender, EventArgs e)
  7.         {
  8.             WinBlock.Unhook();
  9.         }
  10.  
  11.         internal static class WinBlock
  12.         {
  13.             [StructLayout(LayoutKind.Sequential)]
  14.             private struct KBDLLHOOKSTRUCT
  15.             {
  16.                 public Keys key;
  17.                 public int scanCode;
  18.                 public int flags;
  19.                 public int time;
  20.                 public IntPtr extra;
  21.             }
  22.  
  23.             private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
  24.             [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  25.             private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
  26.             [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  27.             private static extern bool UnhookWindowsHookEx(IntPtr hook);
  28.             [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  29.             private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
  30.             [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  31.             private static extern IntPtr GetModuleHandle(string name);
  32.             [DllImport("user32.dll", CharSet = CharSet.Auto)]
  33.             private static extern short GetAsyncKeyState(Keys key);
  34.  
  35.             private static IntPtr ptrHook;
  36.  
  37.            
  38.             private static LowLevelKeyboardProc objKeyboardProcess;
  39.  
  40.             //тут зафиксируем на всякий случай
  41.             private static GCHandle gcObjKeyboardProcess = GCHandle.Alloc(objKeyboardProcess);
  42.  
  43.             private static IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
  44.             {
  45.                 if (nCode >= 0)
  46.                 {
  47.                     KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
  48.                     if (objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.RWin)
  49.                     {
  50.                         return (IntPtr)1;
  51.                     }
  52.                 }
  53.                 return CallNextHookEx(ptrHook, nCode, wp, lp);
  54.             }
  55.            
  56.             //Зачем дважды объявил?
  57.             //private delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, IntPtr lParam);
  58.  
  59.             public static void SetHook()
  60.             {
  61.                 ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
  62.                 objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
  63.                 ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
  64.             }
  65.             public static void Unhook()
  66.             {
  67.                 if (ptrHook != IntPtr.Zero)
  68.                 {
  69.                     UnhookWindowsHookEx(ptrHook);
  70.                     ptrHook = IntPtr.Zero;
  71.                 }
  72.             }
  73.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4.125 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы