UWP デバイス アプリでプリンター メンテナンスを実行する方法

Windows 8.1 では、UWP デバイス アプリで、印刷ヘッドの配置やノズルのクリーンなど、プリンター メンテナンスを実行できます。 このトピックでは、C# バージョンの印刷ジョブ管理とプリンター メンテナンスのサンプルを使用して、双方向通信 (Bidi) をどのように活用すればこのようなデバイス メンテナンスを実行できるかについて説明します。 UWP デバイス アプリ全般の詳細については、「UWP デバイス アプリの概要」を参照してください。

C# バージョンの印刷ジョブの管理とプリンター メンテナンスのサンプルでは、DeviceAppForPrinters2 プロジェクトの DeviceMaintenance.xaml.cs ファイルを使用したプリンター メンテナンスを示します。 Bidi を操作するために、このサンプルでは PrinterExtensionLibrary プロジェクトのプリンター拡張機能ライブラリを使用します。 プリンター拡張機能ライブラリは、v4 印刷ドライバーのプリンター拡張機能インターフェイスにアクセスするための便利な方法を提供します。 詳細については、「プリンター拡張機能ライブラリの概要」を参照してください。

Note

このトピックに示すコード例は、C# バージョンの印刷ジョブの管理とプリンター メンテナンスのサンプルに基づいています。 このサンプルは、JavaScript と C++ でも使用できます。 C++ は COM に直接アクセスできるため、C++ バージョンのサンプルにはコード ライブラリ プロジェクトが含まれていないことにご注意ください。 サンプルをダウンロードして、最新バージョンのコードを確認してください。

プリンター メンテナンス

Windows 8.1 では、デバイス メンテナンスの実装に使用できる v4 プリンター ドライバーに新しいプリンター拡張機能インターフェイス (IPrinterBidiSetRequestCallbackIPrinterExtensionAsyncOperationIPrinterQueue2) が導入されています。 これらのインターフェイスを使用すると、Bidi 要求を非同期でポート モニターに送信でき、デバイスとプロトコル固有のコマンドに変換してからプリンターに送信できるようになります。 詳細については、「デバイスのメンテナンス (v4 プリンター ドライバー)」を参照してください。

ヒント

C# アプリと JavaScript アプリでは、COM API を直接操作できません。 C# または JavaScript の UWP デバイス アプリを作成する場合は、(このトピックに示されているように) プリンター拡張機能ライブラリを使用してこれらのインターフェイスにアクセスします。

前提条件

開始する前に、以下の操作を行います。

  1. v4 プリンター ドライバーを使用してプリンターがインストールされていることを確認します。 詳しくは、「v4 プリンター ドライバーの開発」をご覧ください。

  2. 開発マシンを設定します。 ツールのダウンロードと開発者アカウントの作成については、「概要」を参照してください。

  3. ストアにアプリを関連付けます。 詳細については、「UWP デバイス アプリを作成する」を参照してください。

  4. プリンターをアプリに関連付けるプリンターのデバイス メタデータを作成します。 詳細については、「デバイス メタデータを作成する」を参照してください。

  5. アプリのメイン ページの UI を構築します。 すべての UWP デバイス アプリは [開始] から起動でき、全画面表示で表示されます。 開始エクスペリエンスを使用すると、デバイスの固有のブランドと機能に一致する方法で製品またはサービスを強調できます。 使用できる UI コントロールの種類に特別な制限はありません。 全画面表示エクスペリエンスの設計を開始するには、Microsoft Store 設計原則を参照してください。

  6. C# または JavaScript を使用してアプリを作成する場合は、PrinterExtensionLibrary プロジェクトを UWP デバイス アプリ ソリューションに追加します。 このプロジェクトは、印刷ジョブの管理とプリンター メンテナンスのサンプルにあります。

Note

C++ は COM に直接アクセスできるため、C++ アプリには、COM ベースのプリンター デバイス コンテキストを操作するための別のライブラリは必要ありません。

手順 1: Bidi 要求を準備する

デバイス メンテナンス インターフェイスでは、Bidi 要求が文字列形式の XML データである必要があります。 アプリで意味のある場所であればどこでも、Bidi 要求を作成できます。 たとえば、Bidi 要求を文字列定数として保存したり、ユーザー入力に基づいて動的に作成したりすることができます。 印刷ジョブの管理とプリンター メンテナンスのサンプルでは、OnNavigatedTo メソッドで既定の要求が構成されます。 Bidi の詳細については、「双方向通信」を参照してください。

この例は、OnNavigatedToDeviceMaintenance.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: プリンターを検索する

アプリでプリンターにコマンドを送信する前に、まずプリンターを見つける必要があります。 これを行うために、印刷ジョブの管理とプリンター メンテナンスのサンプルには、(PrinterEnumerationPrinterEnumeration.cs ファイル内に) という名前のクラスが含まれています。 このクラスは、デバイス メタデータを使用してアプリに関連付けられているすべてのプリンターを見つけて、各プリンターの名前とデバイス ID を含む PrinterInfo オブジェクトの一覧を返します。

この例は、EnumeratePrinters_ClickDeviceMaintenance.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 クラスと PrinterInfo クラスの詳細については、PrinterEnumeration.cs ファイルを参照してください。

手順 3: Bidi 要求を送信する

Bidi 要求を送信するには、デバイス メンテナンス インターフェイスに Bidi 文字列とコールバックが必要です。 SendBidiRequest_Click メソッドでは、サンプルは最初に PrinterInfo オブジェクトを使用して、context という名前のプリンター拡張機能コンテキスト オブジェクトを作成します。 すると PrinterBidiSetRequestCallback オブジェクトが作成され、コールバックの OnBidiResponseReceived イベントを処理するイベント ハンドラーが追加されます。 最後に、プリンター拡張機能コンテキストの SendBidiSetRequestAsync メソッドを使用して、Bidi 文字列とコールバックを送信します。

この例は、SendBidiRequest_ClickDeviceMaintenance.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 応答を送信します。

この例は、PrinterBidiSetRequestCallbackDeviceMaintenance.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 スレッドに結果が表示されます。

この例は、OnBidiResponseReceivedDeviceMaintenance.xaml.cs ファイルの メソッドのものです。

internal async void OnBidiResponseReceived(object sender, string bidiResponse)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        BidiResponseOutput.Text = bidiResponse;
    });
}

テスト

UWP デバイス アプリはテストする前に、デバイス メタデータを使用してプリンターにリンクする必要があります。

デバイス アプリ情報をプリンターに追加するには、プリンターのデバイス メタデータ パッケージのコピーが必要です。 デバイス メタデータがない場合は、「UWP デバイス アプリのデバイス メタデータを作成する」トピックの説明に従い、デバイス メタデータ作成ウィザードを使用して作成できます。

Note

デバイス メタデータ作成ウィザードを使用するには、このトピックの手順を完了する前に、Microsoft Visual Studio Professional、Microsoft Visual Studio Ultimate、またはスタンドアロン SDK for Windows 8.1 をインストールする必要があります。 Microsoft Visual Studio Express for Windows をインストールすると、ウィザードを含まないバージョンの SDK がインストールされます。

次の手順に沿ってアプリを作成し、デバイス メタデータをインストールします。

  1. テスト署名を有効にします。

    1. DeviceMetadataWizard.exe をダブルクリックして、%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 からデバイス メタデータ作成ウィザードを開始します。

    2. [ツール] メニューの [テスト署名を有効にする] を選択します。

  2. コンピューターを再起動します

  3. ソリューション (.sln) ファイルを開いてソリューションを構築します。 サンプルが読み込まれた後、F7 キーを押すか、上部のメニューから [Build] -> [ソリューションの構築] に移動します。

  4. プリンターを切断してアンインストールします。 この手順は、次回デバイスが検出されたときに Windows が更新されたデバイス メタデータを読み取るために必要です。

  5. デバイス メタデータを編集して保存します。 デバイス アプリをデバイスにリンクするには、デバイス アプリをデバイスに関連付ける必要があります。 注: デバイス メタデータをまだ作成していない場合は、「UWP デバイス アプリのデバイス メタデータを作成する」を参照してください。

    1. デバイス メタデータ作成ウィザードをまだ開いていない場合は、DeviceMetadataWizard.exe をダブルクリックして、%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 からウィザードを開始します。

    2. [デバイス メタデータの編集] をクリックします。 これにより、既存のデバイス メタデータ パッケージを編集できます。

    3. [開く] ダイアログ ボックスで、UWP デバイス アプリに関連付けられているデバイス メタデータ パッケージを見つけます。 (devicemetadata-ms ファイル拡張子が付いています)

    4. [UWP デバイス アプリ情報の指定] ページで、[UWP デバイス アプリ] ボックスに Microsoft Store アプリ情報を入力します。 [UWP アプリ マニフェスト ファイルのインポート] をクリックすると、[パッケージ名][発行元名][UWP アプリ ID] が自動的に入力されます。

    5. アプリでプリンター通知を登録する場合は、[通知ハンドラー] ボックスを入力します。 [イベント ID] に、印刷イベント ハンドラーの名前を入力します。 [イベント アセット] に、そのコードが駐在するファイルの名前を入力します。

    6. 完了したら、[完了] ページが表示されるまで [次へ] をクリックします。

    7. [デバイス メタデータ パッケージの確認] ページで、すべての設定が正しいことを確認し、[ローカル コンピューターのメタデータ ストアにデバイス メタデータ パッケージをコピーする] チェック ボックスを選択します。 [保存] をクリックします。

  6. デバイスが接続されている場合は、プリンターを再接続して、Windows が更新されたデバイス メタデータを読み取れるようにします。

デバイス メンテナンス (v4 プリンター ドライバー)

v4 印刷ドライバーの開発

双方向通信

UWP アプリの概要

UWP デバイス アプリを作成する (ステップ バイ ステップ ガイド)

UWP デバイス アプリのデバイス メタデータを作成する (ステップ バイ ステップ ガイド)