Ejemplo n.º 1
0
        /// <summary>
        /// Initializes all fields in the print job monitor.
        /// </summary>
        private void Initialize()
        {
            // In the event that the monitor is started while the spooler is offline,
            // keep retrying until the spooler becomes available.
            SafePrinterHandle hPrinter = null;

            while (true)
            {
                try
                {
                    void action() => hPrinter = OpenPrinter(null);

                    Retry.WhileThrowing <Win32Exception>(action, 5, TimeSpan.FromSeconds(30));
                    break;
                }
                catch (Win32Exception ex)
                {
                    switch (ex.NativeErrorCode)
                    {
                    // Ignore these errors.
                    case RPC_S_SERVER_UNAVAILABLE:
                    case RPC_S_CALL_FAILED:
                    case ERROR_INVALID_PRINTER_NAME:
                        Thread.Sleep(TimeSpan.FromSeconds(1));
                        break;

                    default:
                        throw;
                    }
                }
            }

            _options = CreatePrinterNotifyOptions();
            SafePrinterChangeNotificationHandle hChange = FindFirstPrinterChangeNotification(hPrinter, PrinterChanges.Job, _options);

            _hPrinters.Add(hPrinter);
            _hChanges.Add(hChange);
        }
Ejemplo n.º 2
0
 internal static extern bool FindNextPrinterChangeNotification(SafePrinterChangeNotificationHandle hChange, [Out] out uint pdwChange, ref PrinterNotifyOptions pPrinterNotifyOptions, [Out] out SafePrinterNotifyInfoHandle ppPrinterNotifyInfo);
Ejemplo n.º 3
0
 internal static extern SafePrinterChangeNotificationHandle FindFirstPrinterChangeNotification(SafePrinterHandle hPrinter, uint printerChanges, uint fdwOptions, ref PrinterNotifyOptions pPrinterNotifyOptions);
Ejemplo n.º 4
0
        /// <summary>
        /// Retrieves information about the most recent notification for a change notification object associated with a printer or print server.
        /// Call this function when a wait operation on the change notification object is satisfed.
        /// </summary>
        /// <param name="hChange">A handle to a change notification object associated with a printer or print server.</param>
        /// <param name="options">The <see cref="PrinterNotifyOptions" />.</param>
        /// <returns>A <see cref="PrinterNotifyInfoReader" /> containing the notification details.</returns>
        /// <exception cref="Win32Exception">The underlying operation failed.</exception>
        /// <exception cref="System.Exception">
        /// No notification available at this time.
        /// or
        /// Info has been discarded.
        /// </exception>
        private static PrinterNotifyInfoReader FindNextPrinterChangeNotification(SafePrinterChangeNotificationHandle hChange, PrinterNotifyOptions options = new PrinterNotifyOptions())
        {
            if (!NativeMethods.FindNextPrinterChangeNotification(hChange, out _, ref options, out SafePrinterNotifyInfoHandle infoHandle))
            {
                throw new Win32Exception();
            }

            if (infoHandle == null || infoHandle.IsInvalid)
            {
                // Apparently there was no notification after all.  Just return an empty reader.
                return(new PrinterNotifyInfoReader());
            }

            PrinterNotifyInfoReader result = new PrinterNotifyInfoReader(infoHandle);

            // Check to see if data has been discarded.
            if (result.InfoDiscarded)
            {
                result.Dispose();
                return(null);
            }

            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates a change notification object and returns a handle to the object.
        /// </summary>
        /// <param name="hPrinter">A handle to the printer or print server to monitor.</param>
        /// <param name="filter">The <see cref="PrinterChanges" /> that should trigger new events.</param>
        /// <param name="options">The <see cref="PrinterNotifyOptions" /> that dictate which notifications should be sent.</param>
        /// <returns>A handle to a change notification object associated with the specified printer or print server.</returns>
        /// <exception cref="Win32Exception">The underlying operation failed.</exception>
        private static SafePrinterChangeNotificationHandle FindFirstPrinterChangeNotification(SafePrinterHandle hPrinter, PrinterChanges filter, PrinterNotifyOptions options)
        {
            uint fdwOptions = 0; // Must always be zero for 2D printers.
            SafePrinterChangeNotificationHandle result = NativeMethods.FindFirstPrinterChangeNotification(hPrinter, (uint)filter, fdwOptions, ref options);

            if (Marshal.GetLastWin32Error() > 0)
            {
                throw new Win32Exception();
            }

            return(result);
        }