title: C# Keyboard hook throws System.NullReferenceException
body: <p>When discussing keyboard hooking, <a href="http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook" rel="nofollow">this article</a> gets thrown around a lot.</p>
  
  <p>So I tied the class that it suggested:</p>
  
  <pre><code>using System;
      using System.Collections.Generic;
      using System.Text;
      using System.Runtime.InteropServices;
      using System.Windows.Forms;
  
      namespace Utilities {
      /// &lt;summary&gt;
      /// A class that manages a global low level keyboard hook
      /// &lt;/summary&gt;
      class globalKeyboardHook {
      #region Constant, Structure and Delegate Definitions
      /// &lt;summary&gt;
      /// defines the callback type for the hook
      /// &lt;/summary&gt;
      public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);
  
      public struct keyboardHookStruct {
          public int vkCode;
          public int scanCode;
          public int flags;
          public int time;
          public int dwExtraInfo;
      }
  
      const int WH_KEYBOARD_LL = 13;
      const int WM_KEYDOWN = 0x100;
      const int WM_KEYUP = 0x101;
      const int WM_SYSKEYDOWN = 0x104;
      const int WM_SYSKEYUP = 0x105;
      #endregion
  
      #region Instance Variables
      /// &lt;summary&gt;
      /// The collections of keys to watch for
      /// &lt;/summary&gt;
      public List&lt;Keys&gt; HookedKeys = new List&lt;Keys&gt;();
      /// &lt;summary&gt;
      /// Handle to the hook, need this to unhook and call the next hook
      /// &lt;/summary&gt;
      IntPtr hhook = IntPtr.Zero;
      #endregion
  
      #region Events
      /// &lt;summary&gt;
      /// Occurs when one of the hooked keys is pressed
      /// &lt;/summary&gt;
      public event KeyEventHandler KeyDown;
      /// &lt;summary&gt;
      /// Occurs when one of the hooked keys is released
      /// &lt;/summary&gt;
      public event KeyEventHandler KeyUp;
      #endregion
  
      #region Constructors and Destructors
      /// &lt;summary&gt;
      /// Initializes a new instance of the &lt;see cref="globalKeyboardHook"/&gt; class and installs the keyboard hook.
      /// &lt;/summary&gt;
      public globalKeyboardHook() {
          hook();
      }
  
      /// &lt;summary&gt;
      /// Releases unmanaged resources and performs other cleanup operations before the
      /// &lt;see cref="globalKeyboardHook"/&gt; is reclaimed by garbage collection and uninstalls the keyboard hook.
      /// &lt;/summary&gt;
      ~globalKeyboardHook() {
          unhook();
      }
      #endregion
  
      #region Public Methods
      /// &lt;summary&gt;
      /// Installs the global hook
      /// &lt;/summary&gt;
      public void hook() {
          IntPtr hInstance = LoadLibrary("User32");
          hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
      }
  
      /// &lt;summary&gt;
      /// Uninstalls the global hook
      /// &lt;/summary&gt;
      public void unhook() {
          UnhookWindowsHookEx(hhook);
      }
  
      /// &lt;summary&gt;
      /// The callback for the keyboard hook
      /// &lt;/summary&gt;
      /// &lt;param name="code"&gt;The hook code, if it isn't &gt;= 0, the function shouldn't do anyting&lt;/param&gt;
      /// &lt;param name="wParam"&gt;The event type&lt;/param&gt;
      /// &lt;param name="lParam"&gt;The keyhook event information&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public int hookProc(int code, int wParam, ref keyboardHookStruct lParam) {
          if (code &gt;= 0) {
              Keys key = (Keys)lParam.vkCode;
              if (HookedKeys.Contains(key)) {
                  KeyEventArgs kea = new KeyEventArgs(key);
                  if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) &amp;&amp; (KeyDown != null)) {
                      KeyDown(this, kea) ;
                  } else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) &amp;&amp; (KeyUp != null)) {
                      KeyUp(this, kea);
                  }
                  if (kea.Handled)
                      return 1;
              }
          }
          return CallNextHookEx(hhook, code, wParam, ref lParam);
      }
      #endregion
  
      #region DLL imports
      /// &lt;summary&gt;
      /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
      /// &lt;/summary&gt;
      /// &lt;param name="idHook"&gt;The id of the event you want to hook&lt;/param&gt;
      /// &lt;param name="callback"&gt;The callback.&lt;/param&gt;
      /// &lt;param name="hInstance"&gt;The handle you want to attach the event to, can be null&lt;/param&gt;
      /// &lt;param name="threadId"&gt;The thread you want to attach the event to, can be null&lt;/param&gt;
      /// &lt;returns&gt;a handle to the desired hook&lt;/returns&gt;
      [DllImport("user32.dll")]
      static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
  
      /// &lt;summary&gt;
      /// Unhooks the windows hook.
      /// &lt;/summary&gt;
      /// &lt;param name="hInstance"&gt;The hook handle that was returned from SetWindowsHookEx&lt;/param&gt;
      /// &lt;returns&gt;True if successful, false otherwise&lt;/returns&gt;
      [DllImport("user32.dll")]
      static extern bool UnhookWindowsHookEx(IntPtr hInstance);
  
      /// &lt;summary&gt;
      /// Calls the next hook.
      /// &lt;/summary&gt;
      /// &lt;param name="idHook"&gt;The hook id&lt;/param&gt;
      /// &lt;param name="nCode"&gt;The hook code&lt;/param&gt;
      /// &lt;param name="wParam"&gt;The wparam.&lt;/param&gt;
      /// &lt;param name="lParam"&gt;The lparam.&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      [DllImport("user32.dll")]
      static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);
  
      /// &lt;summary&gt;
      /// Loads the library.
      /// &lt;/summary&gt;
      /// &lt;param name="lpFileName"&gt;Name of the library&lt;/param&gt;
      /// &lt;returns&gt;A handle to the library&lt;/returns&gt;
      [DllImport("kernel32.dll")]
      static extern IntPtr LoadLibrary(string lpFileName);
      #endregion
  }
  }
  </code></pre>
  
  <p>It works for a bit, but after using the computer for a while, it will throw a System.NullReferenceException on a random key press. Especially around key combinations.</p>
  
  <p>What could be causing this and how can it be fixed?</p>
  
  <p><strong>EDIT:</strong> This is the code I am using to start the hook:</p>
  
  <pre><code>globalKeyboardHook globalKeyboardHook = new globalKeyboardHook();
  private void Form1_Load(object sender, EventArgs e)
  {
      globalKeyboardHook.KeyDown += gkh_KeyDown;
      globalKeyboardHook.KeyUp += gkh_KeyUp;
      globalKeyboardHook.hook();
  }
  </code></pre>
  
  <p>And this is the complete error I am getting:</p>
  
  <blockquote>
    <p>An unhandled exception of type 'System.NullReferenceException'
    occurred in System.Windows.Forms.dll
         Additional information: Object reference not set to an instance of an object.</p>
  </blockquote>