如何获取打印机和打印作业的状态

文章翻译 文章翻译
文章编号: 160129 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

打印作业的 despool 期间由 Win32 后台处理程序更新打印机和打印作业的状态。在所有其他时间时该打印机不 despooling 并不报告任何状态信息,打印机被认为是准备和空闲。

更多信息

如交给 Win32 API 通过"打印机"由打印机驱动程序、 在打印队列和物理打印机在输入/输出路径。 操作系统将物理打印机视为只是由生成的通过在其余的打印机为这篇文章中引用的系统"打印机,在打印作业的目标。

打印机的最明显的一部分是一个打印队列。它是由打印管理器或 Windows 95 样式的用户界面中的打印机文件夹管理的。打印机驱动程序是该接口由应用程序用来创建通过打印机 dc 的打印作业的打印机。打印机的 I/O 路径包含的系统代码 culminating 与端口监视器的多个图层。

端口监视器是给物理打印机下流末尾的一个系统打印机接口,并负责通过给物理打印机存在任何连接传输数据的打印作业。 在双向打印机的情况下将负责传输数据和从该物理打印机端口监视器。此的连接和该物理打印机是发生错误。它是端口监视器报告这些错误的工作。

后台处理程序不查询将打印机连接到一个物理打印机的状态。相反,物理打印机的状态将决定它通过端口监视器交给时取得成功的打印作业。如果在此过程中发生某些错误,错误是由端口监视器报告和记录在打印作业的状态信息。将后台处理程序反过来,合理错误信息传播到打印机队列。

因此,系统打印机无状态时将报告打印机队列为空。在这种状态打印机则假定为准备好接受打印作业。 这是一个有效的假设,即使该物理打印机处于错误状态如脱机。操作系统会认为可以接受打印作业,即使由于某种原因,它不能完成交付给物理打印机的打印机。这种情况下被视为错误状态,必须解决由用户操作系统中。它不被视为错误可报告成功完成打印作业的后台打印,允许应用程序。

确定物理打印机的状态

没有必须是如果该属性值为 true,则确定物理打印机的状态的一个基本的前提: 后台处理程序必须试图打印作业发送给物理打印机。这是唯一的时间在打印机的状态报告的端口监视器。此外,最有意义的信息可能会报告 JOB_INFO 结构为该特定的打印作业的状态成员中因为某些端口监视器将具有这些值直接设置。

JOB_INFO 结构包含 状态 成员和 pStatus 成员。这两个成员所包含报告的端口监视器的打印作业的状态的信息。这两个成员的不同之处在于该 状态 成员是包含预先确定的值,而 pStatus 成员是一个指向一个字符串,它可以包含几乎任何内容的一个位域的状态。这些值记录由 Win32 SDK 和 WinSpool.h 头文件。pStatus 成员有时,但并非始终如此设置为一个字符串,描述的状态。此字符串的内容被定义的每个端口监视器。

可通过两种 API 函数来返回 JOB_INFO 结构: GetJob 和 EnumJobs。EnumJobs 返回 JOB_INFO 结构的数组而不需要的调用方引用特定作业打印机队列中。当前 despooling (打印) 的打印作业包含状态信息。若要在数组中查找此作业,请搜索来查找打印作业的状态成员具有在 JOB_STATUS_PRINTING JOB_INFO 结构的数组设置的位。

确定打印机状态的一个更容易的方法是检查 PRINTER_INFO 结构的状态成员。此结构由 GetPrinter 函数返回。没有这种方法的缺点在于 PRINTER_INFO 结构可能会提供更详细或广泛的状态信息中没有任何 pStatus 字符串成员。但是,有的一个优点在于端口监视器可能设置更广泛的打印机的某些 PRINTER_INFO 结构的状态位。注意: 为 Windows 默认端口监视器不会将通常设置多个打印机的状态成员的 PRINTER_STATUS_ERROR 位。

请注意状态成员的任何一个结构的集可能包含不严格地给物理打印机相关的状态信息。例如对于 PRINTER_INFO 结构的状态成员可能具有 PRINTER_STATUS_PAUSEDPRINTER_STATUS_PENDING_DELETION,严格地与打印队列相关的设置。此外,JOB_INFO 结构的状态成员可能包含状态值 JOB_STATUS_PAUSEDJOB_STATUS_DELETING,只与该特定的打印作业相关的。同时,请注意打印作业可能会在打印队列中堆积之后它们有交给,将会留下 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;

   }
				
: 在 Windows NT 上启用后打印机池可能有多个打印作业 despooling 从打印机队列将报告状态。此示例代码不会考虑该情况。

参考

调用 Win32 后台处理程序函数的一般说明的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
158828如何调用 Wind32 后台打印程序枚举 api 正确

属性

文章编号: 160129 - 最后修改: 2006年11月21日 - 修订: 4.1
这篇文章中的信息适用于:
  • Microsoft Win32 Application Programming Interface?当用于
    • Microsoft Windows NT Server 3.51
    • Microsoft Windows NT Server 4.0 Standard Edition
    • Microsoft Windows NT Workstation 3.51
    • Microsoft Windows NT Workstation 4.0 开发员版
    • Microsoft Windows 95
关键字:?
kbmt kbfaq kbhowto KB160129 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 160129
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com