Example #1
0
        public void Start()
        {
            if (!WinSpool.OpenPrinter(printerName, out hPrinter, IntPtr.Zero))
            {
                var errorCode = Marshal.GetLastWin32Error();

                throw new SpoolWatcherException($"Error in OpenPrinter: {errorCode}");
            }

            var printerNotifyOptions = new PrinterNotifyOptions();

            printerNotifyOptions.Version = 2;

            var optionsType = CreateOptionsType();

            printerNotifyOptions.Count = (uint)optionsType.Count();

            var pNotifyOptionsSz = Marshal.SizeOf <PrinterNotifyOptions>();

            printerNotifyOptions.pTypes = Marshal.AllocHGlobal(pNotifyOptionsSz * optionsType.Count());

            for (int i = 0; i < optionsType.Count(); i++)
            {
                var ptr = IntPtr.Add(printerNotifyOptions.pTypes, i * pNotifyOptionsSz);

                Marshal.StructureToPtr(optionsType.ElementAt(i), ptr, false);
            }

            notificationHandle = WinSpool.FindFirstPrinterChangeNotification(hPrinter, PrinterChange, (uint)printerNotifyCategory, ref printerNotifyOptions);

            foreach (var optionType in optionsType)
            {
                Marshal.FreeHGlobal(optionType.pFields);
            }

            Marshal.FreeHGlobal(printerNotifyOptions.pTypes);

            if (notificationHandle.IsInvalid)
            {
                var errorCode = Marshal.GetLastWin32Error();

                throw new SpoolWatcherException($"Error in FindFirstPrinterChangeNotification: {errorCode}");
            }

            stopEvent.Reset();

            tNotifications = new Thread(() => WaitForNotifications());

            tNotifications.Start();
        }
Example #2
0
        private void WaitForNotifications()
        {
            var handles = new WaitHandle[] { notificationHandle, stopEvent.WaitHandle };

            while (WaitHandle.WaitAny(handles) == 0)
            {
                if (WinSpool.FindNextPrinterChangeNotification(notificationHandle, out var change, IntPtr.Zero, out SafePrinterNotifyInfo pNotifyInfo))
                {
                    PrinterNotifyInfo printerNotifyInfo = pNotifyInfo;

                    while ((printerNotifyInfo.Flags & PRINTER_NOTIFY_INFO_DISCARDED) == PRINTER_NOTIFY_INFO_DISCARDED)
                    {
                        pNotifyInfo.Close();

                        var notifyOptions = new PrinterNotifyOptions
                        {
                            Flags = PRINTER_NOTIFY_OPTIONS_REFRESH
                        };

                        var nextRet = WinSpool.FindNextPrinterChangeNotification(notificationHandle, out change, notifyOptions, out pNotifyInfo);

                        printerNotifyInfo = pNotifyInfo;

                        if (!nextRet)
                        {
                            break;
                        }
                    }

                    if (SpoolerNotificationReached != null)
                    {
                        var datas = new List <NotificationInfo>();

                        for (uint i = 0; i < printerNotifyInfo.Count; i++)
                        {
                            var notificationInfo = new NotificationInfo();

                            notificationInfo.Id = printerNotifyInfo.aData[i].Id;

                            switch (printerNotifyInfo.aData[i].Type)
                            {
                            case NotifyType.Job:
                                notificationInfo.Type     = NotifyType.Job;
                                notificationInfo.InfoData = DataFieldParser.GetJobTypeData(printerNotifyInfo.aData[i]);
                                break;

                            case NotifyType.Printer:
                                notificationInfo.Type     = NotifyType.Printer;
                                notificationInfo.InfoData = DataFieldParser.GetPrinterTypeData(printerNotifyInfo.aData[i]);
                                break;

                            default:
                                break;
                            }

                            datas.Add(notificationInfo);
                        }

                        var evArgs = new SpoolNotificationEventArgs
                        {
                            PrinterChange     = change,
                            NotificationInfos = datas.ToArray()
                        };

                        SpoolerNotificationReached(this, evArgs);
                    }

                    pNotifyInfo.Close();
                }
            }
        }