如何在 UWP 裝置應用程式中進行印表機維護
在 Windows 8.1 中,UWP 裝置應用程式可以執行印表機維護,例如對齊列印頭和清潔嘴。 本主題使用印表作業管理和印表機維護範例的 C# 版本來示範如何使用雙向通訊 (Bidi) 來執行這類裝置維護。 若要深入瞭解一般 UWP 裝置應用程式,請參閱 滿足 UWP 裝置應用程式。
印表作業管理和印表機維護範例的 C# 版本示範使用 DeviceAppForPrinters2 專案中DeviceMaintenance.xaml.cs檔案的印表機維護。 若要使用 Bidi,此範例會使用 PrinterExtensionLibrary 專案中的印表機延伸模組連結庫。 印表機延伸模組連結庫提供方便的方式來存取 v4 印表驅動程式的印表機延伸模組介面。 如需詳細資訊,請參閱 印表機擴充功能庫概觀。
注意
本主題中顯示的程式代碼範例是以列印作業管理和印表機維護範例的 C# 版本為基礎。 此範例也適用於 JavaScript 和 C++。 請注意,因為 C++ 可以直接存取 COM,因此範例的 C++ 版本不包含程式碼庫專案。 下載範例以查看最新版本的程序代碼。
印表機維護
Windows 8.1 會在 v4 印表機驅動程式中引進新的印表機延伸模組介面,可用來實作裝置維護:IPrinterBidiSetRequestCallback、IPrinterExtensionAsyncOperation 和 IPrinterQueue2。 這些介面可讓您以異步方式將 Bidi 要求傳送至埠監視器,以便轉譯成裝置和通訊協定特定的命令,然後傳送至印表機。 如需詳細資訊,請參閱裝置維護(v4 印表機驅動程式)。
提示
C# 和 JavaScript 應用程式無法直接使用 COM API。 如果您要撰寫 C# 或 JavaScript UWP 裝置應用程式,請使用印表機延伸模組連結庫來存取這些介面(如本主題所示)。
必要條件
開始之前:
請確定您的印表機是使用 v4 印表驅動程式安裝。 如需詳細資訊,請參閱 開發 v4 列印驅動程式。
設定您的開發電腦。 如需下載工具及建立開發人員帳戶的相關信息,請參閱 開始使用 。
將您的應用程式與市集產生關聯。 如需相關信息,請參閱 建立UWP裝置應用程式 。
為您的印表機建立裝置元數據,使其與您的應用程式產生關聯。 如需詳細資訊,請參閱 建立裝置元數據 。
建置應用程式主頁面的UI。 所有UWP裝置應用程式都可以從 [開始] 啟動,其中會顯示全螢幕。 使用 \[開始\] 體驗,以符合您裝置的特定品牌和功能的方式反白顯示您的產品或服務。 它可以使用的UI控制件類型沒有任何特殊限制。 若要開始使用全螢幕體驗的設計,請參閱 Microsoft Store 設計原則。
如果您要撰寫使用 C# 或 JavaScript 撰寫應用程式,請將 PrinterExtensionLibrary 專案新增至 UWP 裝置應用程式解決方案。 您可以在列印作業管理和印表機維護範例中找到此專案。
注意
因為 C++ 可以直接存取 COM,C++ 應用程式不需要個別的連結庫才能使用以 COM 為基礎的印表機裝置內容。
步驟 1:準備 Bidi 要求
裝置維護介面會要求您的 Bidi 要求是字串形式的 XML 數據。 您可以在應用程式中建構您的 Bidi 要求。 例如,您可以將 Bidi 要求儲存為字串常數,或根據使用者輸入動態建立要求。 印表作業管理和印表機維護範例會在方法中OnNavigatedTo
建構預設要求。 如需 Bidi 的詳細資訊,請參閱 雙向通訊。
此範例來自 OnNavigatedTo
DeviceMaintenance.xaml.cs 檔案的方法。
string defaultBidiQuery =
"<bidi:Set xmlns:bidi=\"http://schemas.microsoft.com/windows/2005/03/printing/bidi\">\r\n" +
" <Query schema='\\Printer.Maintenance:CleanHead'>\r\n" +
" <BIDI_BOOL>false</BIDI_BOOL>\r\n" +
" </Query>\r\n" +
"</bidi:Set>";
步驟 2:尋找印表機
您的應用程式必須先找出印表機,應用程式才能將命令傳送至印表機。 若要這樣做,列印作業管理和印表機維護範例會包含名為 PrinterEnumeration
的類別(PrinterEnumeration.cs 檔案中)。 這個類別會尋找透過裝置元數據與應用程式相關聯的所有印表機,並傳回物件清單 PrinterInfo
,其中包含每個印表機的名稱和裝置識別符。
此範例來自 EnumeratePrinters_Click
DeviceMaintenance.xaml.cs 檔案的方法。 它示範範例 PrinterEnumeration
如何使用 類別來取得相關聯的印表機清單。
private async void EnumeratePrinters_Click(object sender, RoutedEventArgs e)
{
try
{
rootPage.NotifyUser("Enumerating printers. Please wait", NotifyType.StatusMessage);
// Retrieve the running app's package family name, and enumerate associated printers.
string currentPackageFamilyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
// Enumerate associated printers.
PrinterEnumeration pe = new PrinterEnumeration(currentPackageFamilyName);
List<PrinterInfo> associatedPrinters = await pe.EnumeratePrintersAsync();
// Update the data binding source on the combo box that displays the list of printers.
PrinterComboBox.ItemsSource = associatedPrinters;
if (associatedPrinters.Count > 0)
{
PrinterComboBox.SelectedIndex = 0;
rootPage.NotifyUser(associatedPrinters.Count + " printers enumerated", NotifyType.StatusMessage);
}
else
{
rootPage.NotifyUser(DisplayStrings.NoPrintersEnumerated, NotifyType.ErrorMessage);
}
}
catch (Exception exception)
{
rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
}
}
提示
如需 和類別的詳細資訊PrinterEnumeration
,請參閱 PrinterEnumeration.cs 檔案。PrinterInfo
步驟 3:傳送 Bidi 要求
若要傳送 Bidi 要求,裝置維護介面需要 Bidi 字串和回呼。 在方法中 SendBidiRequest_Click
,範例會先使用 PrinterInfo
物件來建立名為 的 context
印表機延伸內容物件。 然後會 PrinterBidiSetRequestCallback
建立 物件,並新增事件處理程式來處理回呼的事件 OnBidiResponseReceived
。 最後,印表機延伸內容的方法 SendBidiSetRequestAsync
會用來傳送 Bidi 字串和回呼。
此範例來自 SendBidiRequest_Click
DeviceMaintenance.xaml.cs 檔案的方法。
private void SendBidiRequest_Click(object sender, RoutedEventArgs e)
{
try
{
PrinterInfo queue = (PrinterInfo)PrinterComboBox.SelectedItem;
// Retrieve a COM IPrinterExtensionContext object, using the static WinRT factory.
// Then instantiate one "PrinterExtensionContext" object that allows operations on the COM object.
Object comContext = Windows.Devices.Printers.Extensions.PrintExtensionContext.FromDeviceId(queue.DeviceId);
PrinterExtensionContext context = new PrinterExtensionContext(comContext);
// Create an instance of the callback object, and perform an asynchronous 'bidi set' operation.
PrinterBidiSetRequestCallback callback = new PrinterBidiSetRequestCallback();
// Add an event handler to the callback object's OnBidiResponseReceived event.
// The event handler will be invoked once the Bidi response is received.
callback.OnBidiResponseReceived += OnBidiResponseReceived;
// Send the Bidi "Set" query asynchronously.
IPrinterExtensionAsyncOperation operationContext
= context.Queue.SendBidiSetRequestAsync(BidiQueryInput.Text, callback);
// Note: The 'operationContext' object can be used to cancel the operation if required.
}
catch (Exception exception)
{
rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
}
}
步驟 4:接收 Bidi 回應
當 Bidi “set” 作業完成時,會叫用 類型 PrinterBidiSetRequestCallback
為 的回呼物件。 此回呼會處理來自 HRESULT 回應的錯誤處理,然後觸發 OnBidiResponseReceived
事件,並透過事件參數傳送 Bidi 回應。
此範例顯示 PrinterBidiSetRequestCallback
DeviceMaintenance.xaml.cs 檔案中的類別定義。
internal class PrinterBidiSetRequestCallback : IPrinterBidiSetRequestCallback
{
/// <summary>
/// This method is invoked when the asynchronous Bidi "Set" operation is completed.
/// </summary>
public void Completed(string response, int statusHResult)
{
string result;
if (statusHResult == (int)HRESULT.S_OK)
{
result = "The response is \r\n" + response;
}
else
{
result = "The HRESULT received is: 0x" + statusHResult.ToString("X") + "\r\n" +
"No Bidi response was received";
}
// Invoke the event handlers when the Bidi response is received.
OnBidiResponseReceived(null, result);
}
/// <summary>
/// This event will be invoked when the Bidi 'set' response is received.
/// </summary>
public event EventHandler<string> OnBidiResponseReceived;
}
接著,Bidi 回應會傳送至 OnBidiResponseReceived
方法,其中 Dispatcher
會用來在UI線程上顯示結果。
此範例來自 OnBidiResponseReceived
DeviceMaintenance.xaml.cs 檔案的方法。
internal async void OnBidiResponseReceived(object sender, string bidiResponse)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
BidiResponseOutput.Text = bidiResponse;
});
}
測試
您必須先使用裝置元數據連結到印表機,才能測試 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 在裝置連線時讀取更新的裝置元數據。