Winform 打印PDF顺序混乱,获取打印队列
原文:Winform 打印PDF顺序混乱,获取打印队列

工作中PDF打印顺序混乱着实让我疼痛了好久,其实决绝方法非常简单,但没有想到这个点子的时候确实让我走了很多弯路

这里文章写出来并不是为了炫耀什么,只是觉得发现些好东西就分享出来而已,同时也做个记录,方便以后查找

开始正文

既然要解决打印顺序混乱,那么必须先要实现打印PDF功能,实现PDF打印的方法很多,网上随便一搜就可以找到,这里我贴上自己的打印方法,其实也是网上找到的,稍稍做了修改

Process proc = new Process();
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = itemPath;//打印文件路径(本地完整路径包括文件名和后缀名)
proc.StartInfo.Verb = "print";
proc.Start();
proc.Close();

这个打印方法非常方便,只要你的电脑安装了可以阅读PDF文档的软件,都可以打印,不用特定的软件Adobe Reader、Adobe Acrobat XI等。

但是 当你连续打印多个PDF文档的时候就出现打印顺序混乱的问题,

经调试发现,我发送打印请求的顺和打印机接收到的请求的顺序是不一致的

我的解决方法是当前一个文档打印完成后,再发送下一个打印请求,为此我想到如下方法:

就是在上面的进程打印中添加阻塞;proc.WaitForExit();注释说名的很清楚,等待关联进程退出

代码如下:

                    foreach (var itemPath in filePathList){if (File.Exists(itemPath)){Process proc = new Process();proc.StartInfo.CreateNoWindow = false;proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;proc.StartInfo.UseShellExecute = true;proc.StartInfo.FileName = itemPath;//打印文件路径(本地完整路径包括文件名和后缀名)proc.StartInfo.Verb = "print";proc.Start();proc.WaitForExit();proc.Close();}}

因为PDF打印会关联你的阅读PDF文档软件,因此没打印一个PDF文档就会打开关联软件,这样你必须关掉关联软件才会进入下个打印,这样就很蛋疼了,为此我又做了个线程,这个线程就是实现自动关闭关联软件的功能,但是在使用过程中会发现卡主的现象,这样用户体验不好

因此我想到第二种实现方式:在一个打印请求发送给打印机后,就判断打印机的打印队列中是存在我发送的打印文档,如果没有,则一直等到队列中已存在打印文档后,再发送下一个打印请求,要实现这个功能,你必须要先获取到打印机的打印队列,

首先要获得打印机的名称,我这里使用的是默认打印,为此要获得默认打印机的名称(注:必须是本机的,局域网的没时间研究,等有空了再看看)

        //引入命名空间: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);/// <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 "";}

View Code

然后根据打印机的名称获取本地打印机的打印队列

/// <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();}

View Code

最后在上面的循环打印的方法里加上判断,同时去掉proc.WaitForExit();

                    foreach (string pdfPath in paths){Process proc = new Process();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();string pdfFileName = Path.GetFileName(pdfPath);strPrintName.Append(pdfFileName);strPrintName.Append("\r\n");bool isOk = true;while (isOk){string strJob =GetPrintJobs(defaultPrintName);if (strJob.Contains(pdfFileName)){isOk = false;}}}

另外一种解决方法请看 这里

posted on 2014-05-05 14:13 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3709137.html

Winform 打印PDF顺序混乱,获取打印队列相关推荐

  1. JS实现浏览器打印PDF(使用HttpPrinter打印插件)

    JS实现浏览器打印PDF(使用HttpPrinter打印插件) 第一步:启动HttpPrinter打印插件 第二步:用浏览器打开示例文件\调用示例\websocket协议示例\html\打印pdf.h ...

  2. js打印pdf 使用Adobe reader 打印pdf

    最近工作上有需要在js中打印pdf文件,从中遇到了一些问题,到现在已经解决了,做个记录.希望能帮到有需要的人. 我这边主要采用Adobe reader进行加载打印.                   ...

  3. java中使用pdfBox打印pdf;java web打印pdf;静默打印;jar程序打包成exe文件;exe4j的使用

    java编写打印控件 web打印一直是个棘手的问题,市面上的第三方打印插件也是贵的离谱,这里给出一个可行的解决方案. SpringBoot项目的web服务,实现的功能: 获取电脑可用的打印机列表 设置 ...

  4. android电视打印信息解析,液晶电视获取打印信息的方法与操作

    通过本文我们先来了解一下打印信息,首先要说的就是打印信息并不要打印机,只需要我们的烧录器就可以了.打印信息是什么呢,打印信息是电视机主控送出来的一段代码,我们通过电脑或是手机来查看代码,是机器本身运行 ...

  5. python打印pdf文件_Python静默打印PDF到特定的打印机

    我有一个PDF文档,我想用我的 python应用程序打印它. 我使用的方式是使用命令os.startfile('PDFfile.pdf',"print"),但它打开默认查看器(我的 ...

  6. java从远程服务器获取PDF文件并后台打印(使用pdfFox)

    一.java原生方式打印PDF文件 正反面都打印,还未研究出只打印单面的方法,待解决 public static void printFile(String path) throws Exceptio ...

  7. C# 打印PDF文档的10种方法

    操作PDF文档时,打印是常见的需求之一.针对不同的打印需求,可分多种情况来进行,如设置静默打印.指定打印页码范围和打印纸张大小.双面打印.黑白打印等等.经过测试,下面将对常见的几种PDF打印需求做一些 ...

  8. c++ byte转cbitmap_关于 C++ 打印 PDF 打印及 PDF 转图片、合并

    关于 C++ 打印 PDF 打印及 PDF 转图片.合并 原文: http://www.aqcoder.com/post/42 pdf(Portable Document Format 的简称,意为& ...

  9. python批量打印_python 批量打印PDF

    有一批PDF文件,好几百个,每个只打印第2,3页,双面打印. 网上搜索一波,方案如下: 安装Ghostscript,GhostView,使用gsprint命令打印pdf文件. gsprint命令参数说 ...

最新文章

  1. python难学不-python难学吗-没有编辑基础可以学python吗?
  2. 静静守候属于我们的幸福。坚守我们的约定
  3. 第一周:深度学习引言(Introduction to Deep Learning)
  4. 《团队激励与沟通》第 5 讲——沟通的技巧 重点部分总结
  5. Ansible 管理windwos服务器(一)
  6. 直播课 | 三维人体扫描与AI测量
  7. 重学python入门知识
  8. Apache的详细配置
  9. [红外] 求一个数的反码, 并作为高位追加到 这个数的前面
  10. 书单丨5本经典著作描绘C++学习路线图
  11. oracle12c集群安装—grid安装
  12. 限制编辑的PDF文档没有密码如何破解?
  13. Arduino +合宙ESP32C3 +1.8/1.44 寸TFT液晶屏驱动显示
  14. Channel Attention 通道注意力
  15. jquery append添加的元素用jquery无法获取到
  16. 聚焦质控 | 如何进行单病种过程质量管理
  17. 接口测试用例设计实践总结
  18. 桌面只计算机图标发白,win7系统桌面图标变白怎么回事_电脑桌面图标有小白块...
  19. 电力电子技术填空题(80+道),适合期末复习、面试等
  20. 图:国行HTC 8X修改市场区域

热门文章

  1. 用户画像|产品经理应该如何定位用户
  2. java出现Resource leak: 'input' is never closed 解决方法
  3. android监听方法的耗时时间,Android Studio监听时间变化
  4. Linux下内存泄露工具
  5. linux中一条命令将文件转换为UTF-8格式-解决乱码
  6. centos下git clone报401错误解决办法
  7. Hive----------Cannot find hadoop installation: $HADOOP_HOME m...
  8. C# win10系统调用不了系统自带的软键盘osk.exe
  9. hadoop日志文件
  10. hdfs统计某个目录下的文件数