예제 #1
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
        }
예제 #2
0
        internal void PrinterNotifyWaitCallback(object state, bool timedOut)
        {
            if (_printerHandle == IntPtr.Zero)
            {
                return;
            }

            #region read notification details

            _notifyOptions.Count = 1;
            var    pdwChange = 0;
            IntPtr pNotifyInfo;
            var    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
            var 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
            var info  = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));
            var pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData");
            var 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 (var i = 0; i < data.Count(); i++)
            {
                if ((data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS) &&
                    (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE)
                    )
                {
                    var                jStatus  = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString());
                    var                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
                    {
                        //Trace.WriteLine(ex.Message);
                        pji = null;
                        _objJobDict.TryGetValue(intJobId, out strJobName);
                        if (strJobName == null)
                        {
                            strJobName = string.Empty;
                        }
                    }

                    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, PrinterNotifyWaitCallback, _mrEvent, -1, true);

            #endregion
        }
        /// <summary>
        /// Отлавливается нужное задание и вызывается событие, на которое подписались в вызывающем коде
        /// </summary>
        /// <param name="state"></param>
        /// <param name="timedOut"></param>
        internal void PrinterNotifyWaitCallback(object state, bool timedOut)
        {
            if (_printerHandle == IntPtr.Zero)
            {
                return;
            }

            #region read notification details

            _notifyOptions.Count = 1;
            var    pdwChange = 0;
            IntPtr pNotifyInfo;
            var    bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions,
                                                               out pNotifyInfo);
            _notifyOptions.dwFlags = 0;
            //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
            var 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
            var info  = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));
            var pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData");
            var 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 (var i = 0; i < data.Count(); i++)
            {
                if (data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS
                    &&
                    (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE ||
                     data[i].Type == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_TOTAL_PAGES)
                    )
                {
                    var jStatus = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString());
                    if ((jStatus & JOBSTATUS.JOB_STATUS_DELETING) != 0 ||
                        (jStatus & JOBSTATUS.JOB_STATUS_DELETED) != 0 ||
                        (jStatus & JOBSTATUS.JOB_STATUS_ERROR) != 0)
                    {
                        return;
                    }

                    var                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] = $"'n:{pji.Name}|js:{pji.JobStatus}|pn:{pji.NumberOfPages}|ji:{intJobId}|{Guid.NewGuid().ToString()}'";
                        }
                        strJobName = pji.Name;
                        pji.Refresh();
                    }
                    catch (Exception ex)
                    {
                        pji = null;
                        _objJobDict.TryGetValue(intJobId, out strJobName);
                        if (strJobName == null)
                        {
                            strJobName = string.Empty;
                        }

                        Registry.GetValue <Logger>().Error(ex, "When extract job");
                        return;
                    }

                    if (OnJobStatusChange != null)
                    {
                        //Let us raise the event calls: pqm_OnJobStatusChange
                        JobDetail jobDetails = GetJobDetail(data[i].Id);                                                                             //Get detalis about job
                        OnJobStatusChange(this, new PrintJobChangeEventArgs(intJobId, _objJobDict[intJobId], strJobName, jStatus, jobDetails, pji)); //Set pause for job
                    }
                }
            }

            #endregion

            #region reset the Event and wait for the next event

            _mrEvent.Reset();
            _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, PrinterNotifyWaitCallback, _mrEvent, -1, true);

            #endregion
        }