Winform Print PDF Order confusion, get print queue

Source: Internet
Author: User

Original: Winform print PDF order confusion, get print queue

Working in PDF Printing Order confusion really made me ache for a long time, in fact, the method is very simple, but did not think of this idea when it did let me go a lot of detours

Here the article is not written to show off what, just think found some good things to share it, but also make a record, convenient to find later

Start text

Since the printing order to solve the confusion, you must first realize the printing PDF function, the way to achieve PDF printing a lot of, on-line search can be found, here I paste their own printing method, in fact, also found on the Internet, slightly modified

Newfalse=true= Itempath; // Print file path (local full path includes file name and suffix name) " Print " ;p Roc. Start ();p Roc. Close ();

This printing method is very handy, as long as your computer has software that can read PDF documents, can be printed without the specific software Adobe Reader, Adobe Acrobat XI, etc.

But when you print multiple PDF documents in a row, there's a problem with the print order.

Debugging found that I sent the print request and the printer received the order of the request is inconsistent

My workaround is to send the next print request after the current document has been printed, so I think of the following method:

is to add blocking in the process print above; Proc. WaitForExit (); Note that the name is very clear, waiting for the associated process to exit

The code is as follows:

                    foreach(varItempathinchfilepathlist) {                        if(File.exists (Itempath)) {Process proc=NewProcess (); Proc. Startinfo.createnowindow=false; Proc. Startinfo.windowstyle=System.Diagnostics.ProcessWindowStyle.Hidden; Proc. Startinfo.useshellexecute=true; Proc. Startinfo.filename= Itempath;//Print file path (local full path includes file name and suffix name)Proc. Startinfo.verb ="Print"; Proc.                            Start (); Proc.                            WaitForExit (); Proc.                        Close (); }                    }

Because PDF printing will be associated with your reading PDF document software, so not to print a PDF document will open the associated software, so you have to turn off the affiliate software will go to the next print, so it hurts, so I made a thread, this thread is to implement the automatic shutdown of the associated software function, But in the process of use will find the card owner phenomenon, so that the user experience is not good

So I think of the second implementation: After a print request sent to the printer, the printer in the print queue to determine the existence of the printed document I sent, if not, wait until the queue already exists in the print document, and then send the next print request, to achieve this function, you must first get to the printer's print queue,

First to get the name of the printer, I am using the default printing, to get the name of the default printer (note: Must be local, LAN's no time to study, etc., and then see)

        //introduction of namespaces: Using System.Runtime.InteropServices;[DllImport ("Winspool.drv", CharSet = CharSet.Auto, SetLastError =true)]        Private Static extern BOOLSetDefaultPrinter (stringprintername); [DllImport ("Winspool.drv", CharSet = CharSet.Auto, SetLastError =true)]        Private Static extern BOOLGetDefaultPrinter (StringBuilder Pszbuffer,ref intPcchbuffer); /// <summary>        ///Get the default printer/// </summary>        /// <returns></returns>         Public Static stringGetDefaultPrinter () {Const intError_file_not_found =2; Const intError_insufficient_buffer =122; intPcchbuffer =0; if(GetDefaultPrinter (NULL,refPcchbuffer)) {                return ""; }            intLastwin32error =Marshal.GetLastWin32Error (); if(Lastwin32error = =error_insufficient_buffer) {StringBuilder Pszbuffer=NewStringBuilder (Pcchbuffer); if(GetDefaultPrinter (Pszbuffer,refPcchbuffer)) {                    returnpszbuffer.tostring (); } lastwin32error=Marshal.GetLastWin32Error (); }            if(Lastwin32error = =error_file_not_found) {                return ""; }            return ""; }
View Code

Then get the print queue for the local printer based on the name of the printer

/// <summary>        ///get a printed list of printers/// </summary>        /// <param name= "Printname" >printer name, local</param>        /// <returns>returns the document name string in the print queue, with a comma connection between the multiple</returns>         Public Static stringGetprintjobs (stringprintname) {StringBuilder result=NewStringBuilder ();            INTPTR handle; intFirstjob =0; intNumjobs =127; intpcbneeded; intpcreturned; //Open PrinterOpenPrinter (Printname, outhandle, IntPtr.Zero); //get num bytes required, here we assume the Maxt job for the printer Quest is (0..127)EnumJobs (handle, Firstjob, Numjobs,1, IntPtr.Zero,0, outPcbneeded, outpcreturned); //Allocate unmanaged memoryIntPtr PData =Marshal.allochglobal (pcbneeded); //Get structsEnumJobs (handle, Firstjob, Numjobs,1, PData, pcbneeded, outPcbneeded, outpcreturned); //create array of managed job structsjob_info_1[] Jobs =Newjob_info_1[pcreturned]; //Marshal struct to managed            intPtemp = Pdata.toint32 ();//Start Pointer             for(inti =0; i < pcreturned; ++i) {jobs[i]= (job_info_1) marshal.ptrtostructure (NewINTPTR (ptemp),typeof(job_info_1)); Result.                Append (jobs[i].pdocument); Result. Append (","); Ptemp+ = Marshal.SizeOf (typeof(job_info_1)); }            //Cleanup Unmanaged MemoryMarshal.freehglobal (PData); //Close PrinterClosePrinter (handle); returnresult.        ToString (); }
View Code

Finally, in the above loop printing method to add judgment, while removing Proc. WaitForExit ();

                    foreach(stringPdfpathinchpaths) {Process proc=NewProcess (); Proc. Startinfo.createnowindow=false; Proc. Startinfo.windowstyle=System.Diagnostics.ProcessWindowStyle.Hidden; Proc. Startinfo.useshellexecute=true; Proc. Startinfo.filename=Pdfpath; Proc. Startinfo.verb="Print"; Proc.                        Start (); //Proc. WaitForExit ();Proc.                        Close (); stringPdffilename =Path.getfilename (Pdfpath);                        Strprintname.append (Pdffilename); Strprintname.append ("\ r \ n"); BOOLIsOk =true;  while(isOk) {stringStrjob =getprintjobs (defaultprintname); if(Strjob.contains (pdffilename)) {isOk=false; }                        }                    }

Another way to solve this is to see here.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.