如何判断 Microsoft Print to PDF 打印机驱动程序何时完成?
Posted
技术标签:
【中文标题】如何判断 Microsoft Print to PDF 打印机驱动程序何时完成?【英文标题】:How to tell when Microsoft Print to PDF printer driver is finished? 【发布时间】:2019-04-12 13:16:42 【问题描述】:我的应用程序需要一种廉价的方法来创建 PDF 文件。所以我直接使用Windows API的打印功能(CreateDC()
、StartDoc()
、StartPage()
、EndPage()
、EndDoc()
等),并选择Microsoft Print to PDF em> 打印机驱动程序。
此外,我发现如果我将DOCINFO
结构的lpszOutput
成员设置为文件名,驱动程序会将PDF文件写入命名文件,而不提示用户输入名称。
到目前为止,一切都很好。但是我怎么知道 PDF 文件何时创建?有 spooler API,但驱动程序不一定会因为 spooler 完成而完成。或者我可以创建一个循环来查找文件,但它当然会在它实际完成之前存在。我还考虑过尝试在循环中锁定文件,如果文件尚不存在或仍在被写入,则该文件应该会失败。
但我不禁想知道是否有更直接的方法可以知道 PDF 文件何时准备就绪。
【问题讨论】:
我假设您使用的是 GDI Print API。什么时候打电话给ClosePrinter()
?
@MarkBenningfield:不,我没有,但我没有打电话给OpenPrinter()
。无论哪种方式,都可以很好地创建 PDF。我的问题是知道它何时完成创建。
@4386427:我知道那里有一些免费的库,但它们中的大多数看起来很旧,可能已经过时了。这个问题是11年前的。我认为通过使用打印机驱动程序,它应该非常可靠并且保持最新状态。它工作正常。只是我的代码不知道文件什么时候准备好。
问题是,如何监控打印作业取决于您如何创建打印作业。那么您使用的是哪个打印 API? XPS?打印文档包?
好的,这就是 GDI 打印 API。使用这个link,它使用 GDI Print 检查打印机上打印作业的状态。
【参考方案1】:
如果您使用 GDI 打印 API (wingdi.h),则此 link 显示用于查询打印机上打印作业状态的示例代码。
我包含了链接中的代码,但您可能也想阅读这篇文章。
#include <Windows.h>
#include <wingdi.h>
BOOL GetJobs(HANDLE hPrinter, /* Handle to the printer. */
JOB_INFO_2 **ppJobInfo, /* Pointer to be filled. */
int *pcJobs, /* Count of jobs filled. */
DWORD *pStatus) /* Print Queue status. */
DWORD cByteNeeded,
nReturned,
cByteUsed;
JOB_INFO_2 *pJobStorage = NULL;
PRINTER_INFO_2 *pPrinterInfo = NULL;
/* Get the buffer size needed. */
if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
if (!(pPrinterInfo))
/* Failure to allocate memory. */
return FALSE;
/* Get the printer information. */
if (!GetPrinter(hPrinter,
2,
(LPSTR)pPrinterInfo,
cByteNeeded,
&cByteUsed))
/* Failure to access the printer. */
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
/* Get job storage space. */
if (!EnumJobs(hPrinter,
0,
pPrinterInfo->cJobs,
2,
NULL,
0,
(LPDWORD)&cByteNeeded,
(LPDWORD)&nReturned))
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded);
if (!pJobStorage)
/* Failure to allocate Job storage space. */
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
ZeroMemory(pJobStorage, cByteNeeded);
/* Get the list of jobs. */
if (!EnumJobs(hPrinter,
0,
pPrinterInfo->cJobs,
2,
(LPBYTE)pJobStorage,
cByteNeeded,
(LPDWORD)&cByteUsed,
(LPDWORD)&nReturned))
free(pPrinterInfo);
free(pJobStorage);
pJobStorage = NULL;
pPrinterInfo = NULL;
return FALSE;
/*
* Return the information.
*/
*pcJobs = nReturned;
*pStatus = pPrinterInfo->Status;
*ppJobInfo = pJobStorage;
free(pPrinterInfo);
return TRUE;
BOOL IsPrinterError(HANDLE hPrinter)
JOB_INFO_2 *pJobs;
int cJobs,
i;
DWORD dwPrinterStatus;
/*
* Get the state information for the Printer Queue and
* the jobs in the Printer Queue.
*/
if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
return FALSE;
/*
* If the Printer reports an error, believe it.
*/
if (dwPrinterStatus &
(PRINTER_STATUS_ERROR |
PRINTER_STATUS_PAPER_JAM |
PRINTER_STATUS_PAPER_OUT |
PRINTER_STATUS_PAPER_PROBLEM |
PRINTER_STATUS_OUTPUT_BIN_FULL |
PRINTER_STATUS_NOT_AVAILABLE |
PRINTER_STATUS_NO_TONER |
PRINTER_STATUS_OUT_OF_MEMORY |
PRINTER_STATUS_OFFLINE |
PRINTER_STATUS_DOOR_OPEN))
free(pJobs);
return TRUE;
/*
* Find the Job in the Queue that is printing.
*/
for (i = 0; i < cJobs; i++)
if (pJobs[i].Status & JOB_STATUS_PRINTING)
/*
* If the job is in an error state,
* report an error for the printer.
* Code could be inserted here to
* attempt an interpretation of the
* pStatus member as well.
*/
if (pJobs[i].Status &
(JOB_STATUS_ERROR |
JOB_STATUS_OFFLINE |
JOB_STATUS_PAPEROUT |
JOB_STATUS_BLOCKED_DEVQ))
free(pJobs);
return TRUE;
/*
* No error condition.
*/
free(pJobs);
return FALSE;
【讨论】:
以上是关于如何判断 Microsoft Print to PDF 打印机驱动程序何时完成?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Windows 10 附带的 Microsoft Print To PDF 打印机以编程方式打印到 PDF 文件而不提示 C# 中的文件名
Microsoft print to pdf 现在打印的pdf无法复制搜索怎么回事