Example #1
0
        public void PrinterNotifyWaitCallback(Object state, bool timedOut)
        {
            if (_printerHandle == IntPtr.Zero)
            {
                return;
            }
            #region read notification details
            _notifyOptions.Count = 1;
            int    pdwChange   = 0;
            IntPtr pNotifyInfo = IntPtr.Zero;
            bool   bResult     = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, out pNotifyInfo);
            //If the Printer Change Notification Call did not give data, exit code
            if ((bResult == false) || (((int)pNotifyInfo) == 0))
            {
                return;
            }

            //If the Change Notification was not relgated to job, exit code
            bool bJobRelatedChange = ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) ||
                                     ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) ||
                                     ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) ||
                                     ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB);
            if (!bJobRelatedChange)
            {
                return;
            }
            #endregion

            #region populate Notification Information
            //Now, let us initialize and populate the Notify Info data
            PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));
            int pData = (int)pNotifyInfo + Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO));
            PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count];
            for (uint i = 0; i < info.Count; i++)
            {
                data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA));
                pData  += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA));
            }
            #endregion

            #region iterate through all elements in the data array
            for (int i = 0; i < data.Count(); i++)
            {
                if ((data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS) &&
                    (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE)
                    )
                {
                    JOBSTATUS          jStatus    = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString());
                    int                intJobID   = (int)data[i].Id;
                    string             strJobName = "";
                    PrintSystemJobInfo pji        = null;
                    try
                    {
                        _spooler = new PrintQueue(new PrintServer(), _spoolerName);
                        pji      = _spooler.GetJob(intJobID);
                        if (!objJobDict.ContainsKey(intJobID))
                        {
                            objJobDict[intJobID] = pji.Name;
                        }
                        strJobName = pji.Name;
                    }
                    catch
                    {
                        pji = null;
                        objJobDict.TryGetValue(intJobID, out strJobName);
                        if (strJobName == null)
                        {
                            strJobName = "";
                        }
                    }

                    if (OnJobStatusChange != null)
                    {
                        //Let us raise the event
                        OnJobStatusChange(this, new PrintJobChangeEventArgs(intJobID, strJobName, jStatus, pji));
                    }
                }
            }
            #endregion

            #region reset the Event and wait for the next event
            _mrEvent.Reset();
            _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), _mrEvent, -1, true);
            #endregion
        }
Example #2
0
        public void PrinterNotifyWaitCallback(Object state, bool timedOut)
        {
            ManualResetEvent Mevent       = (ManualResetEvent)state;
            PrinterModel     printerModel = printerModels.FirstOrDefault(o => o.ChangeHandle == Mevent.Handle);

            #region read notification details
            printerModel.NotifyOptions.Count = 1;
            int    pdwChange   = 0;
            IntPtr pNotifyInfo = IntPtr.Zero;
            bool   bResult     = FindNextPrinterChangeNotification(printerModel.ChangeHandle, out pdwChange, printerModel.NotifyOptions, out pNotifyInfo);

            if ((bResult == false) || (((long)pNotifyInfo) == 0))
            {
                return;
            }


            bool bJobRelatedChange = pdwChange > 0;

            if (!bJobRelatedChange)
            {
                return;
            }
            #endregion

            #region populate Notification Information

            PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));
            long pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData");
            PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count];
            for (uint i = 0; i < info.Count; i++)
            {
                data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA));
                pData  += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA));
            }
            #endregion

            #region iterate through all elements in the data array
            for (int i = 0; i < data.Count(); i++)
            {
                if ((data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS) &&
                    (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE))
                {
                    JOBSTATUS          jStatus           = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString());
                    int                intJobID          = (int)data[i].Id;
                    string             strJobName        = "";
                    PrintSystemJobInfo pji               = null;
                    short              shortJobCopies    = 1;
                    uint               uintJobTotalPages = 1;

                    try
                    {
                        printerModel.Spooler = new PrintQueue(new PrintServer(), printerModel.PrinterName);
                        pji = printerModel.Spooler.GetJob(intJobID);
                        if (!objJobDict.ContainsKey(intJobID))
                        {
                            objJobDict[intJobID] = pji.Name;
                        }
                        strJobName = pji.Name;


                        GetJob(printerModel.PrinterHandle, (uint)intJobID, 2, IntPtr.Zero, 0, out uint needed);
                        if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
                        {
                            IntPtr buffer = Marshal.AllocHGlobal((int)needed);
                            GetJob(printerModel.PrinterHandle, (uint)intJobID, 2, buffer, needed, out needed);
                            JOB_INFO_2 jobInfo = (JOB_INFO_2)Marshal.PtrToStructure(buffer, typeof(JOB_INFO_2));
                            DEVMODE    dMode   = (DEVMODE)Marshal.PtrToStructure(jobInfo.pDevMode, typeof(DEVMODE));
                            shortJobCopies    = dMode.dmCopies;
                            uintJobTotalPages = jobInfo.TotalPages;
                            Marshal.FreeHGlobal(buffer);
                        }
                    }
                    catch
                    {
                        pji = null;
                        objJobDict.TryGetValue(intJobID, out strJobName);
                        if (strJobName == null)
                        {
                            strJobName = "";
                        }
                    }

                    OnJobStatusChange?.Invoke(this, new PrintJobChangeEventArgs(intJobID, strJobName, jStatus, pji, uintJobTotalPages, shortJobCopies));
                }
            }
            #endregion

            #region reset the Event and wait for the next event
            try
            {
                printerModel.MrEvent.Reset();
                printerModel.WaitHandle = ThreadPool.RegisterWaitForSingleObject(printerModel.MrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), printerModel.MrEvent, -1, true);
            }
            catch { }
            #endregion
        }
Example #3
0
 public static extern bool FreePrinterNotifyInfo([In] ref PRINTER_NOTIFY_INFO pPrinterNotifyInfo);