在 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的驅動程序支援。
背景工作可以選擇:
不執行任何動作
將通知詳細資料儲存在本機應用程式資料存放區中
更新 UWP 應用程式磚通知
更新 UWP 應用程式通知徽章
傳送 UWP 應用程式快顯通知
動態磁磚通知或快顯通知可讓使用者方便啟動前台應用程式。 啟動前景應用程式時,可以使用 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 檔案的 方法。 它示範如何根據兩個名為title
和body
的字串來發出通知。
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市集應用程式生命週期的詳細資訊,請參閱 應用程式生命週期。
若要判斷您的應用程式是否在其中一個案例中啟動,請處理 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 或 獨立 SDK for Windows 8.1,才能完成本主題中的步驟。 安裝 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 市集應用程式資訊。 按下 [匯入 UWP 應用程式指令清單檔],自動輸入 套件名稱、發行者名稱,UWP 應用程式識別碼。
如果您的 app 正在註冊印表機通知,請填寫 通知處理程式 方塊。 在 事件識別碼中,輸入列印事件處理程序的名稱。 在 [事件資產中,輸入該程序代碼所在的檔名。
完成後,依次點擊 [下一步],直到到達 [完成] 頁面。
在 [檢閱裝置元數據套件] 頁面上,確定所有設定都正確無誤,然後選取 [將裝置元數據套件複製到本機計算機上的元數據存放區 複選框。 然後按下 儲存。
重新連線印表機,讓 Windows 在裝置連線時讀取更新的裝置元數據。
故障排除
問題:沒有出現預設的「Toast 通知」
如果預期時沒有出現預設列印通知...
可能的原因: 測試簽署未開啟。 如需開啟偵錯的相關資訊,請參閱本主題中的偵錯部分。
可能的原因: 網域政策已停用快顯通知。 離開網域,然後再試一次。
可能的原因: 印表機尚未實作 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)
方法。
相關主題
驅動程序對自訂UI的支援