共用方式為


JavaScript 條件約束

重要

新式列印平臺是 Windows 與印表機通訊的慣用方法。 我們建議您使用Microsoft的 IPP 收件匣類別驅動程式,以及列印支援應用程式 (PSA),自定義 Windows 10 和 11 中的列印體驗,以進行印表機裝置開發。

如需詳細資訊,請參閱 新式列印平臺列印支援應用程式設計指南

v4 印表機驅動程式模型支援擴充條件約束的新模型,以及衍生自 v3 IPrintOemPrintTicketProvider 介面的 PrintTicket 處理。

不過,v4 印表機驅動程式會使用 JavaScript 來實作稱為 JavaScript 條件約束的 API,而列印機驅動程式可以視需要實作其中一或多個 API,而不是使用已編譯的組態外掛程式。 如需詳細資訊,請參閱本主題結尾的 JavaScript 條件約束 API 一節中的函式。

JavaScript 條件約束可用來增強 PrintCapabilities、驗證 PrintTickets,以及處理 PrintTicket 轉換成 DEVMODE ,反之亦然。 不過,JavaScript 條件約束有一些限制。 以下是主要限制的清單:

  • 使用 CompletePrintCapabilities 新增的功能和選項,以及 validatePrintTicket 中指定的條件約束不會顯示在桌面印表機喜好設定視窗中。

  • 使用 CompletePrintCapabilities 新增的功能和選項不會保存在公用 DEVMODE 中。

  • JavaScript 條件約束無法從資源 dll 存取語言資源,以當地語系化新增的功能和選項或參數。

因此,我們建議只在適當情況下使用 JavaScript 條件約束。 在 GPD 或 PPD 檔案中應盡可能指定功能和選項,而且只有複雜的條件約束應該以 JavaScript 表示。

偵錯 JavaScript 檔案

開啟以 Windows 為基礎的腳本主機中的 JavaScript 檔案,支援 JavaScript 檔案的基本語法驗證。 若要這樣做,請以滑鼠右鍵按兩下 JavaScript 檔案,然後選取 [開啟 With],然後選擇清單中的 Windows 腳本主機專案。 如果未擲回任何錯誤,則 JavaScript 在語法上是有效的。 否則,它會指出問題的行號,如下列螢幕快照所示。

javascript 語法錯誤對話框。

公開可用的 JavaScript 驗證工具也可能是評估 JavaScript 檔案樣式的助手。

您可以藉由建立下列登入機碼來啟用互動式偵錯:

機碼名稱: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print

數值名稱: EnableJavaScriptDebugging

類型: DWORD

值: 1

不過,由於 PrintConfig.dll 經常載入和卸除,因此對列印的應用程式進行偵錯並不是建議的測試/偵錯策略。 相反地,Microsoft建議製造商建置測試應用程式,以使用這些公用 API 呼叫 JavaScript 條件約束的每個相關進入點:PTGetPrintCapabilities、PTConvertDevModeToPrintTicketPTConvertPrintTicketToDevModePTMergeAndValidatePrintTicket。

僅測試應用程式就足以啟用偵錯,但也有助於新增單元測試,以確保整個驅動程式會如預期般處理 PrintTicket、PrintCapabilities 和條件約束。 如需如何在Visual Studio中建置單元測試的詳細資訊,請參閱下列主題:

Visual Studio Team Test 的單元測試逐步解說

建立上述文字中顯示的登錄機碼並重新啟動裝載進程之後,您可以偵錯 JavaScript 原始程序檔。

請務必注意,如果來源檔案無法剖析,則不會叫用調試程式,而且偵錯環境似乎已失敗。 如果來源檔案無法剖析,請參閱 Windows 腳本主機 以取得如何繼續的詳細資訊。

如果沒有錯誤,而且您的來源檔案已成功剖析,請偵錯您的原始程序檔,如下所示:

  1. 在測試電腦上安裝 Microsoft Visual Studio 2012 或更新版本

  2. 使用具有 JavaScript 程式代碼條件約束的驅動程式建立列印佇列

  3. 將此列印佇列設定為預設值。

  4. 啟動測試應用程式或列印並開始會導致叫用JavaScript條件約束的案例。 應用程式必須呼叫 PrintTicket/PrintCapabilities API,才能闖入 JavaScript 條件約束;記事本等較舊的應用程式不會呼叫這些 API,但 XPS 查看器應用程式會呼叫。 Microsoft建議在這裡使用測試應用程式,因為案例更容易隔離和重現。

  5. 此時,「Visual Studio Just-In-Time 調試程式」將會快顯出「應用程式中>發生<未處理的例外狀況」

  6. 啟動 Visual Studio 2012 或更新版本的新實例

  7. 選擇 [偵錯],然後選擇 [附加至進程]

  8. 在 [附加至進程] 對話框中,確定 [附加至:] 設定為 [腳本程序代碼]

  9. 現在選擇測試應用程式或應用程式列印,最後選擇 [附加]

  10. 點選 [全部中斷]

  11. 現在回到 [Visual Studio Just-In-Time 調試程式] 對話框,然後按兩下 [否]

  12. Visual Studio 會在目前測試所呼叫的位置中斷至調試程式。 您現在可以正常偵錯程序代碼。

JavaScript 條件約束 API

本節會指定做為 API 進入點的函式,以用於 JavaScript 條件約束檔案。 以下是函式:

  • validatePrintTicket

  • completePrintCapabilities

  • convertDevModeToPrintTicket

  • convertPrintTicketToDevMode

validatePrintTicket 函式

呼叫此 API 是為了驗證 PrintTicket 物件對特定印表機是否有效。 這類似於 IPrintOemPrintTicketProvider::ValidatePrintTicket API 的函式。

validatePrintTicket 語法

function validatePrintTicket(printTicket, scriptContext)

validatePrintTicket 參數

  • printTicket

    [in][out]要驗證的 IPrintSchemaTicket 物件。

  • scriptContext

    [in] IPrinterScriptContext 物件,提供驅動程式屬性包、佇列屬性包和使用者屬性包的存取權。

validatePrintTicket 傳回值

傳回值 描述
0 表示 printTicket 參數無效且無法更正。 相當於 E_PRINTTICKET_FORMAT
1 指出 printTicket 參數是這個印表機的有效 PrintTicket 。 相當於 S_PT_NO_CONFLICT
2 表示 printTicket 參數已修改為使其有效。 相當於 S_PT_CONFLICT_RESOLVED

completePrintCapabilities 函式

呼叫此 API 以允許修改 PrintCapabilities 物件。 這應該用於條件式特徵(例如,僅支援相片紙上的無框線)或代表 GPD 或 PPD 檔案無法產生的功能(例如巢狀特徵定義)。 這類似於 IPrintOemPrintTicketProvider::CompletePrintCapabilities API 的函式。

completePrintCapabilities 語法

function completePrintCapabilities(printTicket, scriptContext, printCapabilities)

completePrintCapabilities 參數

  • printTicket

    [in] IPrintSchemaTicket 物件輸入,將產生的 PrintCapabilities 檔限制為 。

  • scriptContext

    [in] IPrinterScriptContext 物件,提供驅動程式屬性包、佇列屬性包和使用者屬性包的存取權。

  • printCapabilities

    [in][out] IPrintSchemaCapabilities 物件,代表組態模組所產生的基底 PrintCapabilities 物件。

completePrintCapabilities 傳回值

無。

convertDevModeToPrintTicket 函式

系統會呼叫此 API,將 DEVMODE 屬性包中的值轉換成 PrintTicket。 這類似於 IPrintOemPrintTicketProvider::ConvertDevModeToPrintTicket API 的函式,不同之處在於此實作會將 DEVMODE 的私人區段封裝成 IPrinterScriptablePropertyBag 物件,而且不允許存取 DEVMODE 的公用區段。

convertDevModeToPrintTicket 語法

function convertDevModeToPrintTicket(devModeProperties, scriptContext, printTicket)

convertDevModeToPrintTicket 參數

  • devModeProperties

[in] 代表 DEVMODE 屬性包的 IPrinterScriptablePropertyBag 物件。

convertDevModeToPrintTicket 傳回值

無。

convertPrintTicketToDevMode 函式

呼叫此 API 以將 PrintTicket 的值轉換成 DEVMODE 屬性包。 這類似於 IPrintOemPrintTicketProvider::ConvertPrintTicketToDevMode API 的函式,不同之處在於此實作會將 DEVMODE 的私人區段封裝到 IPrinterScriptablePropertyBag 物件,而且不允許存取 DEVMODE 的公用區段。

convertPrintTicketToDevMode 語法

function convertPrintTicketToDevMode(printTicket, scriptContext, devModeProperties)

convertPrintTicketToDevMode 參數

  • printTicket

    [in] 代表要轉換之 PrintTicket 的 IPrintSchemaTicket 物件。

  • scriptContext

    [in] IPrinterScriptContext 物件,提供驅動程式屬性包、佇列屬性包和使用者屬性包的存取權。

  • devModeProperties

    [in][out] 代表 DEVMODE 屬性包的 IPrinterScriptablePropertyBag 物件。

convertPrintTicketToDevMode 傳回值

無。

條件約束最佳做法

Windows 8 列印對話框和列印喜好設定體驗僅支援列印架構關鍵詞命名空間的子集。 因此,Microsoft不建議在 Windows 8 列印對話框支援的功能之間使用限制式,或列印喜好設定 UI 和不在該 UI 中的功能,因為使用者沒有機會解決這類條件約束。

例如,如果稱為 Photo 的 PageMediaType 選項限製為只使用 PageResolution 值為 1200dpi,則使用者將無法選擇相片媒體類型。 在這種情況下,最好符合使用者的意圖(相片媒體),並調整任何必要的設定,使這種情況發生。 這些調整可以在 JavaScript 條件約束程式碼中進行。

如果驅動程式未使用 JavaScript 條件約束,則不需要提供檔案。 如果驅動程式只針對進入點的子集使用 JavaScript 條件約束(例如 validatePrintTicket),則應該從 JavaScript 檔案完全省略其他進入點。