如何获取打印机和打印作业的状态
如引用由 Win32API, ” 打印机 ” 由打印机驱动程序, 打印队列, 和输入/输出路径到物理打印机。 操作系统将物理打印机视为只打印作业由生成并传递系统 ” 打印机, ” 作为打印机本文其余部分中引用的目标。
最明显一部分打印机是打印队列。 它是由打印管理器或样式 Windows 95 用户界面中打印机文件夹。 打印机驱动程序是接口到由应用程序用于创建打印作业通过打印机 DC 打印机。 由几层的代码以端口 culminating I/O 打印机的路径。
端口监视器是接口到物理打印机在低流结尾处系统打印机并负责传输数据的打印作业之间存在任何连接到物理打印机。 万一有双向打印机, 端口监视器会负责传输数据和从物理打印机。 此连接, 和物理打印机, 是其中出现错误。 它是作业的端口监视器来报告这些错误。
后台处理程序不查询用于是物理打印机与打印机连接状态不。 同时它是通过端口监视器 despooled 而, 物理打印机的状态确定打印作业的成功。如果某些错误发生在此过程, 错误是由端口监视器报告并打印作业的状态信息中记录。 后台处理程序, 反过来, 传播到打印机队列合理错误信息。
当打印机队列为空因此, 系统打印机报告没有状态。 在此状态, 打印机假定准备好接受打印作业。这是有效假设即使错误中物理打印机是如脱机状态。 操作系统认为打印机准备好接受打印作业, 即使由于某种原因, 它无法完成传递到物理打印机。这些情况被视为错误状态, 必须考虑由用户操作系统中。 就被认为 reportable 到允许以成功完成打印作业的后台应用程序错误。
回到顶端
确定了物理打印机状态
没有一个基本前提, 必须为 true 来确定是物理打印机状态: 后台处理程序必须能试图向物理打印机发送打印作业。这是通过端口监视器报告的打印机状态仅时间。 此外, 最有意义信息可能报告 JOB_INFO 结构对于该特定打印作业的状态成员中因为某些端口监视器将已设置这些值直接。
JOB_INFO 结构包含 状态 成员和 pStatus 成员。 两个成员包含由端口监视器报告打印作业的状态信息。这些两个成员有所不同, 状态 成员是包含预定值, 而 pStatus 成员是可能包含只大约任何字符串指向位字段的状态。 这些值记录由 Win32SDK 和 WinSpool.h 头文件。 pStatus 成员有时, 但不总是, 设置为描述性状态字符串。由每个端口监视器定义该字符串的内容。
JOB_INFO 结构由两个 API 函数返回: GetJob 和 EnumJobs。 调用方引用特定作业 EnumJobs 返回数组 JOB_INFO 结构不需要该打印机队列中。 打印作业, 是当前 despooling (打印) 包含状态信息。 以数组中查找此作业、 搜索 JOB_INFO 结构以查找其状态成员有 JOB_STATUS_PRINTING 打印作业的数组位设置。
是确定打印机状态的方便方法是要检查状态成员 PRINTER_INFO 结构。 由 GetPrinter 函数返回该结构。没有, 没有 PRINTER_INFO 结构可能提供更详细或大量状态信息中没有 pStatus 字符串成员缺点到此方法。 但是, 端口监视器可能设置部分更广泛打印机状态位 PRINTER_INFO 结构的没有优势。 通常用于 Windows 默认端口监视器不设置超过 PRINTER_STATUS_ERROR 位的打印机的状态成员注意,。
注意该状态设置的结构的成员可能包含不严格相关到物理打印机的状态信息。 例如, PRINTER_INFO 结构状态成员可能设置与 PRINTER_STATUS_PAUSED 或 PRINTER_STATUS_PENDING_DELETION , 是严格与打印队列。 还, JOB_INFO 结构状态成员对于 JOB_STATUS_PAUSED 或 JOB_STATUS_DELETING , 是只与特定打印作业包含状态值。 在打印队列中, 打印作业可能堆积它们有 despooled 并将以对 JOB_STATUS_PRINTED 处于后还要, 注意,。
每个这些函数要求句柄到打印机来标识所需打印机。 从 OpenPrinter 函数, 接受包含了打印机名称字符串获得该控点。 此名称可以是本地打印机的名称或者 UNC 共享到网络打印机名称。
以下示例代码演示如何调用 EnumJobs 函数以检索 JOB_INFO 结构正确以及如何调用 GetPrinter 函数以检索 PRINTER_INFO 结构:
示例代码
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;
}
注意 : WindowsNT, 上启用打印机池时可能有多个打印作业从打印机队列, 将报告状态 despooling。 此示例代码并不认为该情况。
欢迎转载,请注明出处:亲亲宝宝