title: Virtual printer port monitor installing
body: <p>I have a port monitor dll, that I instaling by call AddMonitor function of the spooler. But when I want uninstal this monitor, the DeleteMonitor function return errorcode 3008 - "The specified print monitor is currently in use". How I can free my monitor dll?</p>
  
  <pre><code>
  
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
      private class MONITOR_INFO_2
      {
          [MarshalAs(UnmanagedType.LPStr)]
          public string pName;
          [MarshalAs(UnmanagedType.LPStr)]
          public string pEnvironment;
          [MarshalAs(UnmanagedType.LPStr)]
          public string pDLLName;
      }
  
      [DllImport("winspool.Drv", EntryPoint = "AddMonitorA", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      private static extern bool AddMonitor(
      [MarshalAs(UnmanagedType.LPStr)] string Name,
      Int32 Level,
      [In, MarshalAs(UnmanagedType.LPStruct)] MONITOR_INFO_2 mi2);
  
      [DllImport("winspool.Drv", EntryPoint = "DeleteMonitorA", SetLastError = true,  ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      private static extern bool DeleteMonitor(
      [MarshalAs(UnmanagedType.LPStr)] string pNullServerName,
      [MarshalAs(UnmanagedType.LPStr)] string pNullEnvironment,
      [MarshalAs(UnmanagedType.LPStr)] string MonitorName);
  
      private unsafe void InstallMonitor(string monitorName, string dllName)
      {
          MONITOR_INFO_2 mi2 = new MONITOR_INFO_2();
          mi2.pName = monitorName;
          mi2.pEnvironment = null;
          mi2.pDLLName = dllName;
  
          try
          {
              bool bRet = AddMonitor(null, 2, mi2);
              if (!bRet)
                  throw new Win32Exception(Marshal.GetLastWin32Error());
          }
          catch (Exception e)
          {
              if (!DeleteMonitor(null, null, monitorName))
              {
                  throw new Win32Exception(Marshal.GetLastWin32Error());
              }
              bRet = AddMonitor(null, 2, mi2);
              if (!bRet)
                  throw new Win32Exception(Marshal.GetLastWin32Error());
          }
      }
  
  </code></pre>