/// <summary> /// Deletes the given printer from the system /// </summary> /// <param name="printerName">The name of the printer to delete</param> /// <param name="portCreated">If true, the port is deleted as part of this operation</param> public void DeletePrinter(string printerName, bool portCreated) { Precondition.NotNullOrEmpty(printerName, "printerName"); var pDefaults = new SafeNativeMethods.PRINTER_DEFAULTS { DesiredAccess = SafeNativeMethods.PRINTER_ALL_ACCESS, pDatatype = IntPtr.Zero, pDevMode = IntPtr.Zero }; Exception failure = null; /* * Set the port to the default port before deleting the printer. Otherwise the delete may fail because the port is in use */ try { this.UpdatePort(string.Empty, DefaultPort, portCreated, printerName); } catch (Win32Exception) { } catch (VirtualPrinterException) { } for (int retries = 0; ; retries++) { IntPtr hPrinter; if (SafeNativeMethods.OpenPrinter(printerName, out hPrinter, ref pDefaults)) { try { /* * Retry the deletion of the printer for a second or so, just in case * the spooler has not had time to clean up its last print job */ if (!SafeNativeMethods.DeletePrinter(hPrinter)) { if (retries < MaxPrinterDeleteAttempts) { Thread.Sleep(PrinterDeleteRetryDelayMs); continue; } failure = new Win32Exception(Marshal.GetLastWin32Error()); } break; } finally { SafeNativeMethods.ClosePrinter(hPrinter); } } failure = new Win32Exception(Marshal.GetLastWin32Error()); break; } if (failure != null && this.PrinterExists(printerName)) { throw failure; } }