Example #1
0
        /// <summary>
        /// Adds a new port with the given name
        /// </summary>
        /// <param name="portName">The name of the port to add</param>
        /// <exception cref="Win32Exception">Raised when an underlying call fails</exception>
        public void AddPort(string portName)
        {
            Precondition.NotNullOrEmpty(portName, "portName");

            SafeNativeMethods.PORT_INFO_1 pInfo = new SafeNativeMethods.PORT_INFO_1 {
                szPortName = portName
            };

            int result = SafeNativeMethods.AddPortEx(null, 1, ref pInfo, PortMonitor);

            if (result != 0)
            {
                Logger.InfoFormat("Port created with name of {0}", portName);
                return;
            }

            result = Marshal.GetLastWin32Error();
            if (result != 87)
            {
                throw new Win32Exception(result);
            }

            // Double check that the port does, in fact, exist
            if (this.PortExists(portName))
            {
                throw new VirtualPrinterException(string.Format("Port {0} already exists", portName));
            }

            throw new Win32Exception(result);
        }
Example #2
0
        /// <summary>
        /// Creates a new printer on the system
        /// </summary>
        /// <param name="printerName">The name of the printer</param>
        /// <param name="portName">The port to listen on</param>
        /// <param name="driverName">The name of the print driver to use</param>
        /// <param name="printProcessor">The processor to use</param>
        public void CreatePrinter(string printerName, string portName, string driverName, string printProcessor)
        {
            Precondition.NotNullOrEmpty(printerName, "printerName");
            Precondition.NotNullOrEmpty(portName, "portName");
            Precondition.NotNullOrEmpty(driverName, "driverName");
            Precondition.NotNullOrEmpty(printProcessor, "printProcessor");

            SafeNativeMethods.PRINTER_INFO_2 _pInfo = new SafeNativeMethods.PRINTER_INFO_2
            {
                pPrinterName    = printerName,
                pPortName       = portName,
                pDriverName     = driverName,
                pPrintProcessor =
                    printProcessor
            };

            IntPtr hPrinter = SafeNativeMethods.AddPrinter(null, 2, ref _pInfo);

            if (hPrinter != IntPtr.Zero)
            {
                SafeNativeMethods.ClosePrinter(hPrinter);

                Logger.InfoFormat("Printer created with name {0} using port: {1} and driver {2}", printerName, portName, driverName);
            }
            else
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
Example #3
0
        /// <summary>
        /// Returns a value indicating whether a given port is already present
        /// </summary>
        /// <param name="portName">The name of the port to look for</param>
        /// <returns>True if the port exists, otherwise false</returns>
        public bool PortExists(string portName)
        {
            Precondition.NotNullOrEmpty(portName, "portName");

            return
                (GetInstalledPorts()
                 .Any(port => string.Compare(port, portName, StringComparison.InvariantCultureIgnoreCase) == 0));
        }
Example #4
0
        /// <summary>
        /// Updates the printer instance to use a new port
        /// </summary>
        /// <param name="currentPort">The name of the current port in use</param>
        /// <param name="newPort">The new port to listen on</param>
        /// <param name="portCreated">True if the port has already been created</param>
        /// <param name="printerName">The name of the printer</param>
        /// <returns>True if the port was created</returns>
        public bool UpdatePort(string currentPort, string newPort, bool portCreated, string printerName)
        {
            Precondition.NotNull(currentPort, "currentPort");
            Precondition.NotNullOrEmpty(newPort, "newPort");
            Precondition.NotNullOrEmpty(printerName, "printerName");

            bool created = false;

            if (!this.PortExists(newPort))
            {
                this.AddPort(newPort);
                created = true;
            }

            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher(string.Format("SELECT * FROM Win32_Printer WHERE Name='{0}'", printerName));

            string priorPort = string.Empty;

            foreach (ManagementBaseObject printer in searcher.Get())
            {
                var portNameObj = printer["PortName"];
                priorPort           = portNameObj == null ? string.Empty : portNameObj.ToString();
                printer["PortName"] = newPort;

                ManagementObject printerObject = printer as ManagementObject;
                if (printerObject != null)
                {
                    printerObject.Put();                        // Call put to save the settings.
                }
            }

            /* If this application instance created the port, and the new one is different,
             * delete the old one */
            if (priorPort != newPort && !string.IsNullOrEmpty(priorPort))
            {
                this.DeletePort(priorPort);
            }

            return(created);
        }
Example #5
0
        /// <summary>
        /// Returns a value indicating whether the given printer exists
        /// </summary>
        /// <param name="printerName">The name of the printer to check</param>
        /// <returns>True if the printer already exists, false if not</returns>
        public bool PrinterExists(string printerName)
        {
            Precondition.NotNullOrEmpty(printerName, "printerName");

            var defaults = new SafeNativeMethods.PRINTER_DEFAULTS
            {
                DesiredAccess = SafeNativeMethods.PRINTER_ALL_ACCESS,
                pDatatype     = IntPtr.Zero,
                pDevMode      = IntPtr.Zero
            };

            IntPtr hPrinter;

            if (SafeNativeMethods.OpenPrinter(printerName, out hPrinter, ref defaults))
            {
                SafeNativeMethods.ClosePrinter(hPrinter);
                return(hPrinter != IntPtr.Zero);
            }

            return(false);
        }
Example #6
0
        /// <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;
            }
        }