如何取得印表機及列印工作的狀態

文章翻譯 文章翻譯
文章編號: 160129 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

Win32 多工緩衝處理程式會更新的印表機及列印工作狀態,在列印工作 despool 期間。在所有其他時候當該印表機不 despooling,並不報告任何狀態資訊,印表機會被視為準備和閒置。

其他相關資訊

如參照到的 Win32 API,印表機"被組成印表機驅動程式]、 [列印佇列] 和 [輸入/輸出路徑到實體的印表機。 作業系統會將實體印表機視為只是列印工作由產生並通過成一個印表機本文的其餘部分中提及一個系統 「 印表機 」 的目的端。

印表機最可見部份是列印佇列。它是由列印管理員] 或 [Windows 95 樣式使用者介面中的 [印表機] 資料夾管理。印表機驅動程式是介面,以應用程式用它來建立透過印表機 DC 的列印工作的印表機。印表機的 I/O 路徑是由數個層級的系統程式碼 culminating 連接埠監視器所組成。

連接埠監視器是介面,以實體印表機的系統印表機下資料流結尾,而且負責透過任何連接到實體印表機存在傳送列印工作的資料。 在雙向印表機的情況下連接埠監視器會負責轉送資料及傳出實體的印表機。這個連線和實體印表機都是發生錯誤。它是連接埠監視器,來報告這些錯誤的工作。

多工緩衝處理器不會查詢印表機連接的實體印表機的狀態。改,實體印表機的狀態會決定成功的列印工作在 despooled 透過連接埠監視器的時間。如果在此處理程序中發生某些錯誤,錯誤會報告連接埠監視器,並且記錄在列印工作的狀態資訊。多工緩衝處理程式,依序會傳播到印表機佇列的合理錯誤資訊。

因此,系統印表機報告沒有狀態印表機佇列是空白時。在此狀態印表機會假設已準備好接收列印工作。 這是有效的假設,即使實體印表機是在錯誤狀態例如離線。作業系統會視為已準備好接收列印工作,即使基於某些原因,它無法完成傳遞到實體印表機印表機。這種情況下會被視為錯誤狀態必須加以處理由使用者的作業系統中。它不被視為錯誤 reportable 允許順利完成列印工作的多工緩衝處理應用程式。

判斷實體印表機狀態

沒有一個必須為真判斷實體印表機狀態的基本前提: 多工緩衝處理器必須嘗試將列印工作傳送到實體的印表機。這是唯一的時候印表機的狀態報告的連接埠監視器。在另外最有意義的資訊可能會在報告 JOB_INFO 結構對該特定的列印工作的狀態成員,因為某些連接埠監視器會有設定這些值直接。

JOB_INFO 結構包含 狀態 成員和 pStatus 成員。這兩個成員包含連接埠監視器所報告的列印工作的狀態資訊。這些兩個成員不同 狀態 成員是 pStatus 成員的指標,字串可能包含幾乎同時包含預先決定的值的一個位元欄位的狀態。這些值會記錄由 Win32 SDK 和 WinSpool.h 標頭檔。pStatus 成員有時候,但並不一定設定為描述性狀態字串。這個字串的內容是由每個連接埠監視器所定義。

JOB_INFO 結構由兩個 API 函式傳回: 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,只與該特定的列印工作相關的狀態值。也,注意列印工作可能會累積在列印佇列中有 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;

   }
				
注意: 當 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 Developer Edition
    • Microsoft Windows 95
關鍵字:?
kbmt kbfaq kbhowto KB160129 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本: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