OpenPrinter (winspool)
Last changed: -212.159.121.211

.
Summary
Opens a printer handle given the printer name

C# Signatures:

[DllImport("winspool.drv", CharSet=CharSet.Auto, SetLastError=true)]
static extern int OpenPrinter(string pPrinterName, out IntPtr phPrinter, ref PRINTER_DEFAULTS pDefault);

[DllImport("winspool.drv",SetLastError=true)]
static extern int OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);

Both signatures will work fine, it is a matter of whether you need a higher level of access to the printer or not. For 'read' only access such as monitoring printer queues, you don't need to pass in a PRINTER_DEFAULTS instance for the last parameter, you can just pass zero (0) if you declare the extern function pDefault parameter as an int. You will need a PRINTER_DEFAULTS structure if you need to change any properties of the printer such as setting the duplex value of the printer.

VB Signatures:

   <DllImport("winspool.drv", EntryPoint:="OpenPrinterA", _
   SetLastError:=True, CharSet:=CharSet.Ansi, _
   ExactSpelling:=True, _
   CallingConvention:=CallingConvention.StdCall)> _
   Private Shared Function OpenPrinter(ByVal pPrinterName As String, _
        ByRef phPrinter As IntPtr, _
        ByVal pDefault As IntPtr) As Boolean

   <DllImport("winspool.drv", EntryPoint:="OpenPrinterA", ExactSpelling:=True, _
   SetLastError:=True, CallingConvention:=CallingConvention.StdCall, _
   CharSet:=CharSet.Ansi)> _
   Private Shared Function OpenPrinter(ByVal pPrinterName As String, _
   ByRef hPrinter As IntPtr, ByVal pDefault As PRINTER_DEFAULTS) As Boolean
   End Function

  For .NET 2.0 I use:
  <DllImport("winspool.Drv", EntryPoint:="OpenPrinterW", _
       SetLastError:=True, CharSet:=CharSet.Unicode, _
       ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function OpenPrinter(ByVal src As String, ByRef hPrinter As IntPtr, ByVal pd As Integer) As Boolean
    End Function


User-Defined Types:

PRINTER_DEFAULTS

Notes:

As always, only do SetLastError=true if you actually intend to call GetLastError.

ClosePrinter

Tips & Tricks:

Sample Code:

How to cancel a print job:

IntPtr pHandle;
PRINTER_DEFAULTS defaults = new PRINTER_DEFAULTS();
byte b = 0;
OpenPrinter(printerName, out pHandle, defaults);
SetJobA(pHandle, (int)jobID, 0, ref b, (int)Job_Control.Cancel);
ClosePrinter(pHandle);

Alternative Managed API:

The System.Management API allows for lots of printer stuff, but doesn't let you delete a print job in Win2K.

Documentation
OpenPrinter on MSDN