如何使用JNA通过WinspoolUtil和Winspool获取JobInfo2(打印机与作业)
解决JNA获取打印作业信息(WinspoolUtil.getJobInfo2缺失)的问题
我明白你遇到的困扰了——你提到的那个JNA版本的platform模块里,WinspoolUtil确实没有提供getJobInfo2()这个便捷方法,所以得直接调用Winspool的原生API来实现获取JOB_INFO_2格式的打印作业信息。下面是具体的实现步骤和代码示例:
核心思路
要获取JOB_INFO_2结构体的打印作业数据,需要直接调用Windows原生的EnumJobsAPI(JNA已封装该接口)。整体流程是:
- 打开目标打印机,获取打印机句柄
- 调用
EnumJobs枚举作业,指定级别为2(对应JOB_INFO_2结构体) - 解析返回的字节缓冲区为JOB_INFO_2数组
- 关闭打印机句柄,释放系统资源
代码实现示例
import com.sun.jna.Native; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.Winspool; import com.sun.jna.platform.win32.Winspool.JOB_INFO_2; import com.sun.jna.ptr.IntByReference; public class PrintJobProcessor { public static void main(String[] args) { // 替换为你的打印机名称,网络打印机格式为"\\\\服务器名\\打印机名" String targetPrinter = "YourLocalPrinterName"; HANDLE printerHandle = new HANDLE(); IntByReference bufferSizeNeeded = new IntByReference(); IntByReference jobCountReturned = new IntByReference(); try { // 第一步:打开打印机获取句柄 boolean isPrinterOpened = Winspool.INSTANCE.OpenPrinter(targetPrinter, printerHandle, null); if (!isPrinterOpened) { System.err.println("打开打印机失败,请检查打印机名称是否正确"); return; } // 第二步:先调用一次EnumJobs获取所需缓冲区大小 boolean firstEnumSuccess = Winspool.INSTANCE.EnumJobs(printerHandle, 0, 100, 2, null, 0, bufferSizeNeeded, jobCountReturned); if (!firstEnumSuccess && Native.getLastError() != Winspool.ERROR_INSUFFICIENT_BUFFER) { System.err.println("查询作业缓冲区大小失败"); return; } // 第三步:分配缓冲区并再次调用EnumJobs获取实际作业数据 byte[] jobBuffer = new byte[bufferSizeNeeded.getValue()]; boolean secondEnumSuccess = Winspool.INSTANCE.EnumJobs(printerHandle, 0, 100, 2, jobBuffer, jobBuffer.length, bufferSizeNeeded, jobCountReturned); if (!secondEnumSuccess) { System.err.println("枚举打印作业失败"); return; } // 第四步:解析缓冲区为JOB_INFO_2数组并处理 JOB_INFO_2[] jobInfos = JOB_INFO_2.toArray(jobBuffer, jobCountReturned.getValue()); for (JOB_INFO_2 job : jobInfos) { System.out.println("作业ID: " + job.JobId); System.out.println("文档名称: " + job.pDocument); System.out.println("提交用户: " + job.pUserName); // 可根据需求访问更多字段,比如job.Status(作业状态)、job.TotalPages(总页数)等 System.out.println("---"); } } finally { // 最后:关闭打印机句柄,释放资源 if (!printerHandle.equals(HANDLE.INVALID_HANDLE_VALUE)) { Winspool.INSTANCE.ClosePrinter(printerHandle); } } } }
关键参数说明
EnumJobs方法的核心参数含义:
hPrinter:打开打印机后得到的句柄(HANDLE类型)FirstJob:起始枚举的作业ID,传0表示从第一个作业开始NoJobs:最大枚举作业数,可根据实际场景调整(比如100)Level:指定返回的作业信息结构体级别,传2对应JOB_INFO_2pJob:存储作业数据的缓冲区,第一次调用传null仅获取所需大小cbBuf:缓冲区的字节长度pcbNeeded:返回实际需要的缓冲区大小(第一次调用后赋值)pcReturned:返回实际枚举到的作业数量
注意事项
- 建议使用较新版本的JNA和JNA Platform库,减少API缺失问题
- 打印机名称需准确,网络打印机要使用完整的UNC路径格式
- 必须在finally块中关闭打印机句柄,避免系统资源泄漏
内容的提问来源于stack exchange,提问作者user3461158
相关产品推荐
相关产品推荐

