在 UWP 裝置應用程式中使用列印通知
在 Windows 8.1 中,UWP 裝置 app 可以回應從 v4 列印驅動程式傳送的雙向通訊 (Bidi) 事件。 本主題介紹列印通知,並示範列印設定和列印通知範例的 C# 版本如何使用背景工作來回應列印通知。 背景工作示範如何在本機應用程式數據存放區中儲存通知詳細數據、傳送快顯通知,以及更新磚和徽章。 若要深入瞭解一般 UWP 裝置應用程式,請參閱 滿足 UWP 裝置應用程式。
列印設定和列印通知範例的 C# 版本會示範 BackgroundTask 專案中應用程式的背景部分(背景工作)。 背景工作的程式代碼位於 PrintBackgroundTask.cs 檔案中。 前景應用程式可從 [開始] 啟動的全螢幕應用程式位於DeviceAppForPrinters專案中。 InkLevel.xaml.cs檔案顯示可從前景應用程式存取通知詳細數據的方式之一。 若要處理列印通知,此範例會使用 PrinterExtensionLibrary 專案中的印表機延伸模組連結庫。 印表機延伸模組連結庫提供方便的方式來存取 v4 印表驅動程式的印表機延伸模組介面。 如需詳細資訊,請參閱 印表機擴充功能庫概觀。
本主題中顯示的程式代碼範例是以列印設定和列印通知範例的 C# 版本為基礎。 此範例也適用於 JavaScript 和 C++。 請注意,因為 C++ 可以直接存取 COM,因此範例的 C++ 版本不包含程式碼庫專案。 下載範例以查看最新版本的程序代碼。
列印通知
印表通知可讓您的 UWP 裝置應用程式在印表時通知使用者重要的印表機事件,例如紙塞、開啟印表機門、低筆墨水準或印表機紙外錯誤。 當印表機觸發通知時,系統事件代理程式會執行應用程式的背景工作。 從該處,背景工作可以儲存通知詳細數據、傳送快顯通知、更新磚、更新徽章或不執行任何動作。 藉由儲存通知詳細數據,您的應用程式可以提供可協助使用者瞭解並修正印表機問題的體驗。
印表機製造商必須在其 v4 印表驅動程式中實作 Bidi 和 DriverEvent XML 檔案,才能搭配其 UWP 裝置應用程式使用列印通知。 如需詳細資訊,請參閱 雙向通訊。
當 DriverEvent 發生,並啟動 UWP 裝置應用程式的背景工作時,應用程式有數個選項可繼續進行。 如需導致啟動工作之流程的詳細資訊,請參閱 自定義UI的驅動程序支援。
背景工作可以選擇:
不執行任何動作
磚通知或快顯通知可讓使用者方便啟動前景應用程式。 啟動前景應用程式時,可以使用 OnLaunched
App.xaml.cs 中的方法來檢查它是否由磚或快顯通知啟動。 如果是,前景應用程式可以存取本機應用程式數據存放區中的任何列印通知詳細數據。
必要條件
開始之前:
請確定您的印表機是使用 v4 印表驅動程式安裝。 如需詳細資訊,請參閱 開發 v4 列印驅動程式。
設定您的開發電腦。 如需下載工具及建立開發人員帳戶的相關信息,請參閱 開始使用 。
將您的應用程式與市集產生關聯。 如需相關信息,請參閱 建立UWP裝置應用程式 。
為您的印表機建立裝置元數據,使其與您的應用程式產生關聯。 如需詳細資訊,請參閱 建立裝置元數據 。
建置應用程式主頁面的UI。 所有UWP裝置應用程式都可以從 [開始] 啟動,其中會顯示全螢幕。 使用 \[開始\] 體驗,以符合您裝置的特定品牌和功能的方式反白顯示您的產品或服務。 它可以使用的UI控制件類型沒有任何特殊限制。 若要開始使用全螢幕體驗的設計,請參閱 Microsoft Store 設計原則。
如果您要撰寫使用 C# 或 JavaScript 撰寫應用程式,請將 PrinterExtensionLibrary 和 DeviceAppForPrintersLibrary 專案新增至 UWP 裝置應用程式解決方案。 您可以在 [列印設定] 和 [列印通知] 範例中找到這些專案。
因為 C++ 可以直接存取 COM,C++ 應用程式不需要個別的連結庫才能使用以 COM 為基礎的印表機裝置內容。
步驟 1:註冊背景工作
為了讓 Windows 能夠辨識應用程式可以處理列印通知,它必須註冊列印通知的背景工作延伸模組。 此延伸模組會在 元素中 Extension
宣告,屬性 Category
設定為 windows.backgroundTasks
,且 EntryPoint
屬性設定為 BackgroundTask.PrintBackgroundTask
。 延伸模組也包含 Task
元素,指出它支援 systemEvent
工作類型。
您可以在 Microsoft Visual Studio 中指令清單設計工具的 [宣告] 索引標籤上新增列印背景工作延伸模組。 您也可以使用 XML (Text) 編輯器手動編輯應用程式套件指令清單 XML。 以滑鼠右鍵按兩下 方案總管中的 Package.appxmanifest 檔案以進行編輯選項。
此範例會顯示 元素中的 Extension
背景工作延伸模組,因為它出現在應用程式套件指令清單檔 Package.appxmanifest 中。
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Identity Name="Microsoft.SDKSamples.DeviceAppForPrinters.CS" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="1.0.0.0" />
<Properties>
<DisplayName>Device App For Printers C# sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Assets\storeLogo-sdk.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3.0</OSMinVersion>
<OSMaxVersionTested>6.3.0</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="DeviceAppForPrinters" Executable="$targetnametoken$.exe" EntryPoint="DeviceAppForPrinters.App">
<VisualElements DisplayName="Device App For Printers C# sample" Logo="Assets\squareTile-sdk.png"
SmallLogo="Assets\smallTile-sdk.png" Description="DeviceAppForPrinters C# sample"
ForegroundText="light" BackgroundColor="#00b2f0" ToastCapable="true">
<DefaultTile ShowName="allLogos" ShortName="App4PrinterCS" WideLogo="Assets\tile-sdk.png" />
<SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
</VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTask.PrintBackgroundTask">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
<Extension Category="windows.printTaskSettings" Executable="$targetnametoken$.exe" EntryPoint="DeviceAppForPrinters.App" />
</Extensions>
</Application>
</Applications>
</Package>
步驟 2:設定裝置元數據
當您使用 [裝置元數據撰寫精靈] 將應用程式與裝置產生關聯時,請務必完成 [指定 UWP 裝置應用程式資訊] 頁面上的 [通知處理程式] 方塊。 這有助於確保應用程式的背景工作會在列印通知期間呼叫。
如需如何編輯裝置元數據的逐步指示,請參閱 測試 一節。
步驟 3:建置 UI
在建置您的應用程式之前,您應該與設計師和行銷小組合作,以設計用戶體驗。 用戶體驗應該投影貴公司的品牌層面,並協助您建立與用戶的連線。
設計指導方針
在設計磚和徽章體驗之前,請務必先檢閱 Microsoft Store 應用程式指導方針。 指導方針可協助確保您的 app 提供與其他 UWP app 一致的直覺式體驗。
針對您應用程式的主頁面,請記住,Windows 8.1 可以在單一監視器上以各種大小顯示多個應用程式。 請參閱下列指導方針,以深入瞭解您的應用程式如何在螢幕大小、視窗大小和方向之間正常重排。
最佳作法
請勿在通知中包含動作字組。 在通知訊息上,請勿使用可告知使用者推播、按下或按下或按下通知的文字。 用戶已經了解他們可以按下快顯通知來找出詳細資訊。 例如,只要撰寫「印表機的筆跡不足」,而不是「印表機的筆跡不足」。 按 以疑難解答」。
讓互動保持簡單。 通知體驗上顯示的所有項目都應該與通知相關。 例如,關於紙塞的通知頁面應該只包含解決該問題的連結和資訊。 它不應包含購買筆跡或其他支持資訊等不相關的體驗連結。
使用多媒體。 使用裝置的實際相片、影片或圖例,協助使用者快速解決其裝置的問題。
將使用者保留在應用程式的內容中。 提供問題的相關信息時,請勿連結至在線或其他支持數據。 將使用者保留在應用程式的內容中。
步驟 4:建立背景工作
如果您的 app 註冊列印通知的背景工作,則必須提供背景工作啟用的處理程式。 在 [ 列印設定] 和 [列印通知 ] 範例中,類別 PrintBackgroundTask
會處理列印通知。
如果您的印表機狀態不需要立即使用者介入,請更新磚,而不是顯示快顯通知。 例如,對於低筆墨條件,磚更新就已足夠。 但是,如果印表機完全失墨,應用程式可能會顯示快顯通知。
儲存通知詳細數據
背景工作無法直接啟動前景應用程式,只有使用者可以:從磚、快顯通知或開始。 因此,為了確保前景應用程式可以存取列印通知詳細數據,背景工作會將它們儲存到本機記憶體。 如需使用本機記憶體的詳細資訊,請參閱 快速入門:本機應用程式數據。
觸發列印通知時,Windows 會藉由呼叫其 Run
方法執行背景工作。 通知數據會透過必須轉換成類型 Windows.Devices.Printers.Extensions.PrintNotificationEventDetails 的方法參數傳遞至背景工作。 該 PrinterName
物件的 和 EventData
屬性分別帶有印表機名稱和 Bidi 訊息。
本範例顯示背景工作Run
的方法,在PrintBackgroundTask.cs檔案中,列印通知詳細數據會儲存至應用程式設定,再呼叫快顯通知、磚和徽章方法。
public void Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance)
{
// Save notification details to local storage
PrintNotificationEventDetails details = (PrintNotificationEventDetails)taskInstance.TriggerDetails;
settings.Values[keyPrinterName] = details.PrinterName;
settings.Values[keyAsyncUIXML] = details.EventData;
// Demonstrate possible actions
ShowToast(details.PrinterName, details.EventData);
UpdateTile(details.PrinterName, details.EventData);
UpdateBadge();
}
更新磚
當列印通知詳細數據傳送至 UpdateTile
方法時,範例的背景工作會示範如何在磚上顯示它們。 如需磚的詳細資訊,請參閱 磚和磚通知概觀。
此範例會在 PrintBackgroundTask.cs 檔案中顯示背景工作UpdateTile
的方法。
void UpdateTile(string printerName, string bidiMessage)
{
TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
tileUpdater.Clear();
XmlDocument tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150Text09);
XmlNodeList tileTextAttributes = tileXml.GetElementsByTagName("text");
tileTextAttributes[0].InnerText = printerName;
tileTextAttributes[1].InnerText = bidiMessage;
TileNotification tileNotification = new TileNotification(tileXml);
tileNotification.Tag = "tag01";
tileUpdater.Update(tileNotification);
}
更新徽章
UpdateBadge
方法示範如何使用 BadgeNotification 類別來更新徽章。 如需磚的詳細資訊,請參閱 徽章概觀。
此範例會在 PrintBackgroundTask.cs 檔案中顯示背景工作UpdateBadge
的方法。
void UpdateBadge()
{
XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeGlyph);
XmlElement badgeElement = (XmlElement)badgeXml.SelectSingleNode("/badge");
badgeElement.SetAttribute("value", "error");
var badgeNotification = new BadgeNotification(badgeXml);
BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badgeNotification);
}
引發快顯通知
快顯通知是用戶暫時性訊息,其中包含相關的時間敏感性資訊,並提供應用程式中相關內容的快速存取。 快顯通知應該以邀請使用者身分返回您的應用程式,以追蹤感興趣的內容。 如需詳細資訊,請參閱 快顯通知概觀。
若要啟用快顯通知,應用程式必須在應用程式套件指令清單中註冊支援快顯通知。 在 元素中 VisualElements
,將 ToastCapable
屬性設定為 true。
重要
我們不建議一律顯示快顯通知,特別是針對無法採取動作的事件。 這可能會讓使用者煩惱,並導致他們關閉應用程式的所有快顯通知。 對於不需要使用者立即注意的事件,建議只更新磚和徽章,而不會顯示快顯通知。
這個範例會顯示 ToastCapable
元素中的 VisualElements
屬性,因為它出現在應用程式套件指令清單檔 Package.appxmanifest 中。
<VisualElements DisplayName="Device App For Printers C# sample" Logo="Assets\squareTile-sdk.png"
SmallLogo="Assets\smallTile-sdk.png" Description="DeviceAppForPrinters C# sample"
ForegroundText="light" BackgroundColor="#00b2f0" ToastCapable="true">
<DefaultTile ShowName="allLogos" ShortName="App4PrinterCS" WideLogo="Assets\tile-sdk.png" />
<SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
</VisualElements>
此範例來自 ShowToast
PrintBackgroundTask.cs 檔案的方法。 它示範如何根據名為 和body
的title
兩個字串來引發快顯通知。
void ShowToast(string title, string body)
{
//
// Get Toast template
//
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
//
// Pass to app as eventArgs.detail.arguments
//
((XmlElement)toastXml.SelectSingleNode("/toast")).SetAttribute("launch", title);
//
// The ToastText02 template has 2 text nodes (a header and a body)
// Assign title to the first one, and body to the second one
//
XmlNodeList textList = toastXml.GetElementsByTagName("text");
textList[0].AppendChild(toastXml.CreateTextNode(title));
textList[1].AppendChild(toastXml.CreateTextNode(body));
//
// Show the Toast
//
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
步驟 5:處理啟用
列印通知觸發背景工作之後,您可以點選快顯通知或磚來啟動應用程式。 如果您的應用程式是從其中一個啟動,則會透過 LaunchActivatedEventArgs.arguments
屬性將參數傳遞至應用程式。 如需啟用和 Microsoft Store 應用程式生命週期的詳細資訊,請參閱 應用程式生命週期。
若要判斷您的應用程式是否在其中一個案例中啟動,請處理 OnLaunched
事件,並檢查傳遞至事件處理程式的事件自變數。 如果事件自變數為 Null,則應用程式已由使用者從 [開始] 啟動。 如果事件自變數不是 Null,應用程式會從快顯通知或磚啟動。
此範例來自 OnLaunched
App.xaml.cs 檔案的 方法。 它示範如何處理快顯通知或磚的啟用。
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// Associate the frame with a SuspensionManager key
SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
// Restore the saved session state only when appropriate
try
{
await SuspensionManager.RestoreAsync();
}
catch (SuspensionManagerException)
{
//Something went wrong restoring state.
//Assume there is no state and continue
}
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null || !String.IsNullOrEmpty(args.Arguments))
{
// When the navigation stack isn't restored or there are launch arguments
// indicating an alternate launch (e.g.: via toast or secondary tile),
// navigate to the appropriate page, configuring the new page by passing required
// information as a navigation parameter
if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
{
throw new Exception("Failed to create initial page");
}
}
// Ensure the current window is active
Window.Current.Activate();
}
步驟 6:存取通知詳細數據
因為背景工作無法直接啟動前景應用程式,所以列印通知詳細數據必須儲存至應用程式的設定,讓前景應用程式可以存取它們。 如需使用本機記憶體的詳細資訊,請參閱 快速入門:本機應用程式數據。
此範例示範如何從印表設定和列印通知範例中的應用程式設定擷取印表機名稱和 Bidi 訊息。 程式代碼來自 DisplayBackgroundTaskTriggerDetails
InkLevel.xaml.cs 檔案的方法。 請注意,索引鍵索引值 keyPrinterName
和 keyAsyncUIXML
是背景工作中使用的相同字串常數, PrintBackgroundTask.cs。
void DisplayBackgroundTaskTriggerDetails()
{
String outputText = "\r\n";
try
{
string printerName = settings.Values[keyPrinterName].ToString();
outputText += ("Printer name from background task triggerDetails: " + printerName);
}
catch (Exception)
{
outputText += ("No printer name retrieved from background task triggerDetails ");
}
outputText += "\r\n";
try
{
string asyncUIXML = settings.Values[keyAsyncUIXML].ToString();
outputText += ("AsyncUI xml from background task triggerDetails: " + asyncUIXML);
}
catch (Exception)
{
outputText += ("No asyncUI xml retrieved from background task triggerDetails ");
}
ToastOutput.Text += outputText;
}
測試
您必須先使用裝置元數據連結到印表機,才能測試 UWP 裝置應用程式。
您需要印表機的裝置元數據套件複本,才能將裝置應用程式資訊新增至該套件。 如果您沒有裝置元數據,您可以使用裝置元數據撰寫精靈來建置它,如為 UWP 裝置應用程式建立裝置元數據主題中所述。
若要使用 裝置元數據撰寫精靈,您必須先安裝 Microsoft Visual Studio Professional、Microsoft Visual Studio Ultimate 或 適用於 Windows 8.1 的獨立 SDK,才能完成本主題中的步驟。 安裝 Microsoft Visual Studio Express for Windows 會安裝不包含精靈的 SDK 版本。
下列步驟會建置您的應用程式並安裝裝置元數據。
啟用測試簽署。
按兩下 DeviceMetadataWizard.exe,從 %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 啟動裝置元數據撰寫精靈
從 [ 工具] 功能表中,選取 [ 啟用測試簽署]。
重新啟動電腦
開啟方案 (.sln) 檔案來建置方案。 按 F7,或從範例載入後,從頂端功能表移至 [建>置方案 ]。
中斷連線並卸載印表機。 需要此步驟,Windows 會在下次偵測到裝置時讀取更新的裝置元數據。
編輯並儲存裝置元數據。 若要將裝置應用程式連結至您的裝置,您必須將裝置應用程式與裝置產生關聯。
如果您尚未建立裝置元數據,請參閱 建立 UWP 裝置應用程式的裝置元數據。
如果裝置元數據撰寫精靈尚未開啟,請按兩下DeviceMetadataWizard.exe,從 %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 加以啟動。
按兩下 [ 編輯裝置元數據]。 這可讓您編輯現有的裝置元數據套件。
在 [ 開啟 ] 對話框中,找出與您的 UWP 裝置應用程式相關聯的裝置元數據套件。 (它有 devicemetadata-ms 擴展名。)
在 [ 指定 UWP 裝置應用程式資訊 ] 頁面上,於 [UWP 裝置應用程式] 方塊中 輸入 Microsoft Store 應用程式 資訊。 按兩下 [匯入 UWP 應用程式指令清單檔案],自動輸入套件名稱、發行者名稱和 UWP 應用程式識別碼。
如果您的 app 正在註冊印表機通知,請填寫 [ 通知處理程式] 方塊 。 在 [事件標識符] 中,輸入列印事件處理程序的名稱。 在 [事件資產] 中,輸入該程序代碼所在的檔名。
完成時,請按 [下一步] ,直到到達 [完成 ] 頁面為止。
在 [ 檢閱裝置元數據套件 ] 頁面上,確定所有設定都正確,然後選取 [ 將裝置元數據套件複製到本機計算機上的 元數據存放區] 複選框。 然後按一下 [儲存] 。
重新連線印表機,讓 Windows 在裝置連線時讀取更新的裝置元數據。
疑難排解
問題:沒有出現預設快顯通知
如果預期時沒有出現預設列印通知...
可能的原因: 測試簽署未開啟。 如需開啟偵錯的相關信息,請參閱本主題中的偵錯一節。
可能的原因: 網域原則已停用快顯通知。 離開網域,然後再試一次。
可能的原因: 印表機尚未實作 DriverEvents。 檢查您的 v4 驅動程式是否支援 Bidi 和 DriverEvents。 如需詳細資訊,請參閱 自定義UI的驅動程序支援。
可能的原因: 機器在印表機佇列中沒有最近的作業。 請確定印表機圖示顯示在螢幕右下角。 如果沒有,請傳送另一個列印作業。
可能的原因: 背景工作的進入點與
IBackgroundTask
前景應用程式位於相同的專案中。 這是不允許的。 分隔背景工作處理程式的全新類別。可能的原因: 應用程式中通知進入點的類別在指令清單或裝置元數據中不正確,導致應用程式在 backgroundhost 內當機,而不會顯示任何快顯通知。 請檢查下列項目:
請確定已正確在指令清單設計工具的 [宣告] 索引標籤中指定進入點。 它的格式應該是 C# 和 C++ 的 Namespace.ClassName。 針對 JavaScript,它應該是.js檔案的相對目錄路徑。
JavaScript 應用程式在完成之後應該呼叫 close()。
C# 類別必須實作 Windows.ApplicationModel.Background.IBackgroundTask,而且必須有公用 void
Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance)
方法。C++ 類別必須實作 Windows::ApplicationModel::Background::IBackgroundTask,而且必須有
virtual void Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance^ taskInstance)
方法。