PrinterHelper.cs 4.0 KB
using System;
using System.Runtime.InteropServices;

namespace BLL
{
    public static class PrinterHelper
    {
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool OpenPrinter(string pPrinterName, out IntPtr hPrinter, IntPtr pDefault);

        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool ClosePrinter(IntPtr hPrinter);

        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool GetPrinter(IntPtr hPrinter, int dwLevel, IntPtr pPrinter, int cbBuf, out int pcbNeeded);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        private struct PRINTER_INFO
        {
            public string pServerName;
            public string pPrinterName;
            public string pShareName;
            public string pPortName;
            public string pDriverName;
            public string pComment;
            public string pLocation;
            public IntPtr pDevMode;
            public string pSepFile;
            public string pPrintProcessor;
            public string pDatatype;
            public string pParameters;
            public IntPtr pSecurityDescriptor;
            public uint Attributes;
            public uint Priority;
            public uint DefaultPriority;
            public uint StartTime;
            public uint UntilTime;
            public uint Status;
            public uint cJobs;
            public uint AveragePPM;
        }



        public static string GetPrinterStatus(string PrinterName)
        {
            int intValue = GetPrinterStatusInt(PrinterName);
            string strRet = intValue switch
            {
                0 => "准备就绪(Ready)",
                0x00000200 => "忙(Busy)",
                0x00400000 => "被打开(Printer Door Open)",
                0x00000002 => "错误(Printer Error)",
                0x00008000 => "初始化(Initializing)",
                0x00000100 => "正在输入,输出(I/O Active)",
                0x00000020 => "手工送纸(Manual Feed)",
                0x00040000 => "无墨粉(No Toner)",
                0x00001000 => "不可用(Not Available)",
                0x00000080 => "脱机(Off Line)",
                0x00200000 => "内存溢出(Out of Memory)",
                0x00000800 => "输出口已满(Output Bin Full)",
                0x00080000 => "当前页无法打印(Page Punt)",
                0x00000008 => "塞纸(Paper Jam)",
                0x00000010 => "打印纸用完(Paper Out)",
                0x00000040 => "纸张问题(Page Problem)",
                0x00000001 => "暂停(Paused)",
                0x00000004 => "正在删除(Pending Deletion)",
                0x00000400 => "正在打印(Printing)",
                0x00004000 => "正在处理(Processing)",
                0x00020000 => "墨粉不足(Toner Low)",
                0x00100000 => "需要用户干预(User Intervention)",
                0x20000000 => "等待(Waiting)",
                0x00010000 => "热机中(Warming Up)",
                _ => "未知状态(Unknown Status)",
            };
            return strRet;
        }



        private static int GetPrinterStatusInt(string PrinterName)
        {
            int result = 0;
            bool rtn = OpenPrinter(PrinterName, out IntPtr hPrinter, IntPtr.Zero);
            if (!rtn) return result;

            GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out int cbNeeded);
            if (cbNeeded > 0)
            {
                IntPtr pAddr = Marshal.AllocHGlobal(cbNeeded);
                rtn = GetPrinter(hPrinter, 2, pAddr, cbNeeded, out _);
                if (rtn)
                {
                    PRINTER_INFO info = (PRINTER_INFO)Marshal.PtrToStructure(pAddr, typeof(PRINTER_INFO));
                    result = Convert.ToInt32(info.Status);
                }
                Marshal.FreeHGlobal(pAddr);
            }
            ClosePrinter(hPrinter);

            return result;
        }




    }
}