C# 获取打印机队列的打印任务

发布时间 2023-04-20 13:55:38作者: ziff123
 //引入命名空间:using System.Runtime.InteropServices;
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool SetDefaultPrinter(string printerName);

        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool GetDefaultPrinter(StringBuilder pszBuffer, ref int pcchBuffer);

        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct JOB_INFO_1
        {
            public int JobId;
            public string pPrinterName;
            public string pMachineName;
            public string pUserName;
            public string pDocument;
            public string pDatatype;
            public string pStatus;
            public int Status;
            public int Priority;
            public int Position;
            public int TotalPages;
            public int PagesPrinted;
            public SYSTEMTIME Submitted;
        }

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool ClosePrinter(IntPtr hPrinter);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern int EnumJobs(IntPtr hPrinter, int FirstJob, int NoJobs, int Level, IntPtr pInfo, int cdBuf,
                                          out int pcbNeeded, out int pcReturned);

        private static void peekPrinterJobs(string printerToPeek)
        {
            IntPtr handle;
            int FirstJob = 0;
            int NumJobs = 127;
            int pcbNeeded;
            int pcReturned;

            // open printer
            OpenPrinter(printerToPeek, out handle, IntPtr.Zero);

            // get num bytes required, here we assume the maxt job for the printer quest is 128 (0..127)
            EnumJobs(handle, FirstJob, NumJobs, 1, IntPtr.Zero, 0, out pcbNeeded, out pcReturned);

            // allocate unmanaged memory
            IntPtr pData = Marshal.AllocHGlobal(pcbNeeded);

            // get structs
            EnumJobs(handle, FirstJob, NumJobs, 1, pData, pcbNeeded, out pcbNeeded, out pcReturned);

            // create array of managed job structs
            JOB_INFO_1[] jobs = new JOB_INFO_1[pcReturned];

            // marshal struct to managed
            int pTemp = pData.ToInt32(); //start pointer
            for (int i = 0; i < pcReturned; ++i)
            {
                jobs[i] = (JOB_INFO_1)Marshal.PtrToStructure(new IntPtr(pTemp), typeof(JOB_INFO_1));
                pTemp += Marshal.SizeOf(typeof(JOB_INFO_1));
            }

            // cleanup unmanaged memory
            Marshal.FreeHGlobal(pData);

            // close printer
            ClosePrinter(handle);

            // printer jobs are in the jobs array now, do what you want to...
        }
        /// <summary>
        /// 获取默认打印机 
        /// </summary>
        /// <returns></returns>
        public static string GetDefaultPrinter()
        {
            const int ERROR_FILE_NOT_FOUND = 2;

            const int ERROR_INSUFFICIENT_BUFFER = 122;

            int pcchBuffer = 0;

            if (GetDefaultPrinter(null, ref pcchBuffer))
            {
                return "";
            }

            int lastWin32Error = Marshal.GetLastWin32Error();

            if (lastWin32Error == ERROR_INSUFFICIENT_BUFFER)
            {
                StringBuilder pszBuffer = new StringBuilder(pcchBuffer);
                if (GetDefaultPrinter(pszBuffer, ref pcchBuffer))
                {
                    return pszBuffer.ToString();
                }

                lastWin32Error = Marshal.GetLastWin32Error();
            }
            if (lastWin32Error == ERROR_FILE_NOT_FOUND)
            {
                return "";
            }
            return "";
        }

        /// <summary>
        /// 获取打印机的打印列表
        /// </summary>
        /// <param name="printName">打印机名称,本地</param>
        /// <returns>返回打印队列中文档名称字符串,多个之间用逗号连接</returns>
        public static string GetPrintJobs(string printName)
        {
            StringBuilder result = new StringBuilder();

            IntPtr handle;
            int FirstJob = 0;
            int NumJobs = 127;
            int pcbNeeded;
            int pcReturned;

            // open printer 
            OpenPrinter(printName, out handle, IntPtr.Zero);

            // get num bytes required, here we assume the maxt job for the printer quest is 128 (0..127) 
            EnumJobs(handle, FirstJob, NumJobs, 1, IntPtr.Zero, 0, out pcbNeeded, out pcReturned);

            // allocate unmanaged memory 
            IntPtr pData = Marshal.AllocHGlobal(pcbNeeded);

            // get structs 
            EnumJobs(handle, FirstJob, NumJobs, 1, pData, pcbNeeded, out pcbNeeded, out pcReturned);

            // create array of managed job structs 
            JOB_INFO_1[] jobs = new JOB_INFO_1[pcReturned];

            // marshal struct to managed 
            int pTemp = pData.ToInt32(); //start pointer 
            for (int i = 0; i < pcReturned; ++i)
            {
                jobs[i] = (JOB_INFO_1)Marshal.PtrToStructure(new IntPtr(pTemp), typeof(JOB_INFO_1));
                result.Append(jobs[i].pDocument);
                result.Append(",");
                pTemp += Marshal.SizeOf(typeof(JOB_INFO_1));
            }

            // cleanup unmanaged memory 
            Marshal.FreeHGlobal(pData);

            // close printer 
            ClosePrinter(handle);

            return result.ToString();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            string strJob = GetPrintJobs(textBox2.Text);
            strJob = string.IsNullOrWhiteSpace(strJob) ? "" : strJob;
            textBox3.Text = textBox3.Text + strJob + "\r\n";
        }