USB デバイスとの対話、開始から終了まで (UWP アプリ)
この記事では、USB デバイスと通信する UWP アプリを作成するエンド ツー エンドのチュートリアルを提供します。
Windows ランタイム API を使用して、ユーザーが周辺機器の USB デバイスにアクセスできるようにする UWP アプリを作成します。 そのようなアプリは、ユーザーが指定した条件に基づいてデバイスに接続したり、デバイスに関する情報を取得したり、デバイスにデータを送信したり、逆にデバイスからデータ ストリームを取得したり、デバイスをポーリングして割り込みデータを取得したりできます。
ここでは、UWP アプリでこれらのタスクを実装する方法と、Windows.Devices.Usb に含まれるクラスの使用方法を示す例へのリンクについて説明します。 アプリ マニフェストで必要なデバイス機能と、デバイスが接続したときにアプリを起動する方法について説明します。 さらに、バッテリ寿命を節約するためにアプリが一時停止されているときでも、バックグラウンドでデータ転送タスクを実行する方法について説明します。
チュートリアル—USB デバイス用の UWP アプリの作成
この記事の手順に従うか、「カスタム USB デバイス アクセス サンプル」に直接スキップします。 このコンパニオン サンプルでは、ここでのすべての手順を実装していますが、動きを維持するため、コードの手順については説明しません。 特定の手順には、コードをすばやく見つけるのに役立つ「サンプルで確認する」セクションがあります。 サンプルのソース ファイルの構造はシンプルでフラットなため、複数のソース ファイルをドリルダウンしなくても簡単にコードを見つけることができます。 ただし、独自のプロジェクトを別の方法で分割して整理することもできます。
Microsoft WinUSB ドライバーのインストール
マイクロソフトによって提供される WinUSB ドライバーをデバイスのファンクション ドライバーとしてインストールします。
クイック スタート: WinUSB (Winusb.sys) のインストール
Winusb.sys は、次の方法でインストールできます。
- デバイスを接続すると、デバイスが WinUSB デバイスであるため、Windows により Winusb.sys が自動的に読み込まれることに気付く場合があります。
- デバイス マネージャーでシステム提供のデバイス クラスを指定し、ドライバーをインストールします。
- カスタム INF を使用してドライバーをインストールします。 次の 2 つの方法のいずれかで INF を取得できます。
- ハードウェア ベンダーから INF を取得します。
- マイクロソフトにより提供された Winusb.inf ファイルを参照するカスタム INF を記述します。 詳細については、「WinUSB (Winusb.sys) のインストール」を参照してください。
デバイスに関する情報の取得
デバイスに関するデバイス インターフェイス GUID、ハードウェア ID、およびデバイス クラス情報を取得します。
その情報は、デバイスの製造元から入手できます。
ベンダーと製品の識別子
デバイス マネージャーで、デバイスのプロパティを表示します。 [詳細] タブで、[ハードウェア ID] プロパティの値を表示します。 この値は、これら 2 つの識別子の組み合わせです。 たとえば、SuperMUTT デバイスの場合、 ハードウェア ID は「USB\VID_045E&PID_F001」、ベンダー ID は「0x045E」で、製品 ID は「0xF001」です。
デバイス クラス、サブクラス、プロトコル コード
デバイス インターフェイス GUID
または、レジストリの情報を表示することもできます。 詳細については、「USB デバイスのレジストリ エントリ」を参照してください。
USB API セットでデバイス クラス、サブクラス、プロトコルが許可されているかどうかを確認する
デバイスのデバイス クラス、サブクラス、プロトコル コードが次の一覧にある場合、UWP アプリを記述できます。
name:cdcControl, classId:02 * *
name:physical, classId:05 * *
name:personalHealthcare, classId:0f 00 00
name:activeSync, classId:ef 01 01
name:palmSync, classId:ef 01 02
name:deviceFirmwareUpdate, classId:fe 01 01
name:irda, classId:fe 02 00
name:measurement, classId:fe 03 *
name:vendorSpecific, classId:ff * *
基本的な Visual Studio プロジェクトの作成
このチュートリアルで拡張できる基本的な Visual Studio プロジェクトを作成します。
詳細については、「UWP アプリの概要」を参照してください。
アプリ マニフェストへの USB デバイス機能の追加
アプリ マニフェストに USB デバイス機能を追加する方法について説明します。
クイック スタート: アプリ マニフェストに USB デバイス機能を追加する方法
テキスト エディターで Package.appxmanifest ファイルを開き、この例に示すように Name 属性が "usb" に設定された DeviceCapability 要素を追加します。
Note
Visual Studio で USB デバイスの機能を変更することはできません。 ソリューション エクスプローラーで Package.appxmanifestファイルを右クリックし、[プログラムから開く] を選択し、[XML (テキスト) エディター] を選択する必要があります。 ファイルはプレーン XML で開きます。
<Capabilities>
<!--When the device's classId is FF * *, there is a predefined name for the class.
You can use the name instead of the class id.
There are also other predefined names that correspond to a classId.-->
<m2:DeviceCapability Name="usb">
<!--SuperMutt Device-->
<m2:Device Id="vidpid:045E 0611">
<!--<wb:Function Type="classId:ff * *"/>-->
<m2:Function Type="name:vendorSpecific"/>
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
サンプルで確認する: USB デバイスの機能は Package.appxmanifest ファイルにあります。
通信用にデバイスを開く
アプリを拡張して、通信用にデバイスを開きます。
クイック スタート: USB デバイスに接続する方法 (UWP アプリ)
- 列挙されたデバイス コレクション内のデバイスを検索するための検索条件を含む高度なクエリ構文 (AQS) 文字列を作成し、デバイスを検索します。
- 次の 2 つの方法のいずれかでデバイスを開きます。
AQS を FindAllAsync に渡し、デバイスの DeviceInformation オブジェクトを取得します。
詳しくは、「クイック スタート: よく使用されるデバイスの列挙」をご覧ください。
DeviceWatcher オブジェクトを作成することにより、デバイスがシステムに追加またはシステムから削除されるタイミングを検出します。
- AQS を CreateWatcher に渡し、DeviceWatcher オブジェクトを取得します。
- DeviceWatcher オブジェクトにイベント ハンドラーを登録します。
- Added イベント ハンドラーで、デバイスの DeviceInformation オブジェクトを取得します。
- DeviceWatcher オブジェクトを開始および停止します。
詳細については、「デバイスが追加、削除、または変更された場合に通知を受け取る方法」を参照してください。
- DeviceInformation.Id プロパティからデバイス インスタンスを取得します。
- デバイス インスタンス文字列を渡して FromIdAsync を呼び出し、UsbDevice オブジェクトを取得します。
サンプルで確認する: Scenario1_DeviceConnect という名前のファイルを参照してください。
USB デバイスのレイアウトの調査
USB デバイスのレイアウトを調べます。
デバイスの構成とデータ転送の実行に関する基本的な USB の概念を確認します: すべての USB 開発者向けの概念。
デバイス構成記述子、サポートされている各代替設定のインターフェイス記述子、およびそのエンドポイント記述子を表示します。 USBView を使用して、すべての USB コントローラーと接続されている USB デバイスを参照し、デバイスの構成を調べることができます。
UI での USB 記述子の取得および表示
UI で USB 記述子を取得して表示するようアプリを拡張します。
クイック スタート: USB 記述子を取得する方法 (UWP アプリ)
UsbDevice.DeviceDescriptor 値を取得することにより、デバイス記述子を取得します。
UsbConfiguration.ConfigurationDescriptor 値を取得することにより、構成記述子を取得します。
- UsbConfiguration.Descriptors プロパティを取得することにより、完全な構成記述子セットを取得します。
UsbConfiguration.UsbInterfaces プロパティを取得して、構成内のインターフェイスの配列を取得します。
UsbInterface.InterfaceSettings を取得して、代替設定の配列を取得します。
アクティブな代替設定内で、パイプを列挙し、関連付けられたエンドポイントを取得します。
これらのオブジェクトは、エンドポイント記述子を表します。
サンプルで確認する:Scenario5_UsbDescriptors という名前のファイルを参照してください。
ベンダーによって定義された USB コントロール転送の送信
ベンダーによって定義された USB コントロール転送を送信するようアプリを拡張します。
クイック スタート: USB コントロール転送要求を送信する方法 (UWP アプリ)
- デバイスのハードウェア仕様からベンダー コマンドを取得します。
- UsbSetupPacket オブジェクトを作成し、さまざまなプロパティを設定してセットアップ パケットを設定します。
- 転送の方向に応じて、次のメソッドによってコントロール転送を送信する非同期操作を開始します。
サンプルで確認する: Scenario2_ControlTransfer という名前のファイルを参照してください。
一括データの読み取りまたは書き込み
アプリを拡張し、一括データの読み取りまたは書き込みを行います。
クイック スタート: USB 一括転送要求を送信する方法 (UWP アプリ)
- 一括パイプ オブジェクト (UsbBulkOutPipe または UsbBulkInPipe) を取得します。
- ポリシー パラメーターを設定するよう一括パイプを構成します。
- DataReader オブジェクトまたは DataWriter オブジェクトを使用して、データ ストリームを設定します。
- DataReader.LoadAsync または DataWriter.StoreAsync を呼び出して、非同期転送操作を開始します。
- 転送操作の結果を取得します。
サンプルで確認する: Scenario4_BulkPipes という名前のファイルを参照してください。
ハードウェア割り込みデータの取得
ハードウェア割り込みデータを取得するようアプリを拡張します。
クイック スタート: USB 割り込み転送要求を送信する方法 (UWP アプリ)
- 割り込みパイプ オブジェクト (UsbInterruptInPipe または UsbInterruptOutPipe) を取得します。
- DataReceived イベントの割り込みハンドラーを実装します。
- イベント ハンドラーを登録して、データの受信を開始します。
- イベント ハンドラーの登録を解除して、データの受信を停止します。
サンプルで確認する: Scenario3_InterruptPipes という名前のファイルを参照してください。
現在アクティブではないインターフェイス設定の選択
現在アクティブではないインターフェイス設定を選択するようアプリを拡張します。
クイック スタート: USB インターフェイス設定を選択する方法 (UWP アプリ)
デバイスを通信用に開くと、既定のインターフェイスとその最初の設定が選択されます。 この設定を変更する場合、次の手順を実行します。
- UsbInterfaceSetting.Selected 値を使用することにより、USB インターフェイスのアクティブな設定を取得します。
- UsbInterfaceSetting.SelectSettingAsync を呼び出して非同期操作を開始して、USB インターフェイス設定を設定します。
デバイスを閉じる
アプリを拡張してデバイスを閉じます。
クイック スタート: USB デバイスに接続する方法 (UWP アプリ)
UsbDevice オブジェクトの使用が完了したら、デバイスを閉じます。
C++ アプリでは、delete キーワードを使用して参照を解放する必要があります。 C#/VB アプリでは、UsbDevice.Dispose メソッドを呼び出す必要があります。 JavaScript アプリは UsbDevice.Close を呼び出す必要があります。
サンプルで確認する: Scenario1_DeviceConnect という名前のファイルを参照してください。
デバイス メタデータ パッケージの作成
アプリのデバイス メタデータ パッケージを作成します。
Tool: Device メタデータ作成ウィザード
- Windows ドライバー キット (WDK) がインストールされている場合、ドライバー>デバイス メタデータ>作成を開きます。
- スタンドアロン SDK がインストールされている場合、ツールは <install_path>\bin\x86\DeviceMetadataWizardexe にあります。
ウィザードの手順に従って、アプリをデバイスに関連付けます。 デバイスに関するこの情報を入力します。
- [デバイス情報] ページで、[モデル名]、[製造元]、[説明] を入力します。
- ハードウェア情報ページで、デバイスのハードウェア ID を入力します。
アプリをデバイスの特権アプリとして宣言するには、以下の手順に従います。
アプリ情報ページの [特権アプリケーション] グループで、[パッケージ名]、[発行元名]、[UWP アプリ ID] を入力します。
Note
[カスタム ドライバーにアクセスする] オプションはオンにしないでください。
[完了] タブを開きます。[パッケージをシステムのローカル メタデータ ストアにコピーする] チェック ボックスをオンにします。
デバイスを接続し、コントロール パネルで [デバイスとプリンターの表示] を開き、デバイスのアイコンが正しいことを確認します。
サンプルで確認する: DeviceMetadata フォルダーを参照してください。
自動再生のアクティブ化の実装
自動再生のアクティブ化を実装してアプリを拡張し、デバイスがシステムに接続されたときにアプリを起動します。
クイック スタート: 自動再生デバイスのアプリを登録する
自動再生機能を追加して、デバイスがシステムに接続されたときにアプリが起動するようにすることができます。 すべての UWP アプリに対して自動再生を有効にできます (特権または他の権限)。
デバイス メタデータ パッケージで、デバイスが自動再生通知に応答する方法を指定する必要があります。 [Windows 情報] タブで、[UWP デバイス アプリ] オプションを選択し、次のようにアプリ情報を入力します。
アプリ マニフェストで、次に示すように、自動再生デバイス宣言と起動情報を追加します。
App クラスの OnActivated メソッドで、デバイスがアプリをアクティブ化したかどうかをチェックします。 その場合、メソッドは、DeviceInformation.Id プロパティ値を含む DeviceEventArgs パラメーター値を受け取ります。 これは、「通信のためにデバイスを開く」で説明されているのと同じ値です。
サンプルで確認する: 自動再生という名前のファイルを参照してください。 JavaScript については、default.js を参照してください。
バックグラウンド タスクの実装
アプリを拡張し、デバイスへの長時間の転送を実行できるバックグラウンド タスク (アプリが中断されることなくファームウェアを更新するなど) を実装します。
バックグラウンド タスクを実装するには、2 つのクラスが必要です。
バックグラウンド タスク クラスは IBackgroundTask インターフェイスを実装し、周辺機器を同期または更新するために作成する実際のコードを含みます。 バックグラウンド タスク クラスは、バックグラウンド タスクがトリガーされたときに、アプリのアプリケーション マニフェストで指定されたエントリ ポイントから実行されます。
Note
Windows 8.1 によって提供されるデバイスのバックグラウンド タスク インフラストラクチャ。 Windows バックグラウンド タスクの詳細については、「バックグラウンド タスクによるアプリのサポート」をご覧ください。
バックグラウンド タスク クラス
- Windows バックグラウンド タスク インフラストラクチャで必要な IBackgroundTask インターフェイスを実装します。
- Run メソッドでそのクラスに渡される DeviceUseDetails インスタンスを取得し、このインスタンスを使用して Microsoft Store アプリに進行状況を報告し、キャンセル イベントに登録します。
- Run メソッドは、バックグラウンド デバイス同期コードを実装するプライベートの OpenDevice メソッドと WriteToDeviceAsync メソッドも呼び出します。
UWP アプリは、DeviceUseTrigger バックグラウンド タスクを登録してトリガーします。 アプリは、バックグラウンド タスクの進行状況を登録、トリガー、処理します。
Note
次のコード例は、対応するオブジェクトを使用して DeviceServicingTrigger バックグラウンド タスクに適用できます。 2 つのトリガー オブジェクトとそれに対応する API の唯一の違いは、Windows によって行われるポリシー チェックです。
- DeviceUseTrigger オブジェクトと BackgroundTaskRegistration オブジェクトを作成します。
- このサンプル アプリケーションで以前登録されたバックグラウンド タスクがあるかどうかを確認し、タスクの Unregister メソッドを呼び出してそれらをキャンセルします。
- デバイスと同期するバックグラウンド タスクを登録します。 SetupBackgroundTask メソッドは、次の手順で SyncWithDeviceAsync メソッドから呼び出されます。
- DeviceUseTrigger を初期化し、後で使用するために保存します。
- BackgroundTaskBuilder オブジェクトを作成し、その Name、TaskEntryPoint、SetTrigger の各プロパティとメソッドを使用して、アプリの DeviceUseTrigger オブジェクトとバックグラウンド タスク名を登録します。 BackgroundTaskBuilder オブジェクトの TaskEntryPoint プロパティは、バックグラウンド タスクがトリガーされたときに実行されるバックグラウンド タスク クラスの完全な名前に設定されます。
- バックグラウンド タスクからの完了イベントと進行状況イベントを登録し、Microsoft Store アプリが完了と進行状況の更新をユーザーに提供できるようにします。
- プライベート SyncWithDeviceAsync メソッドは、デバイスと同期するバックグラウンド タスクを登録して、バックグラウンド同期を開始します。
前の手順から SetupBackgroundTask メソッドを呼び出し、デバイスと同期するバックグラウンド タスクを登録します。
バックグラウンド タスクを開始するプライベート StartSyncBackgroundTaskAsync メソッドを呼び出します。
デバイスへのアプリのハンドルを閉じて、バックグラウンド タスクが開始時にデバイスを開くことができるようにします。
Note
バックグラウンド タスクは更新を実行するためにデバイスを開く必要があるため、Microsoft Store アプリは RequestAsync を呼び出す前にデバイスへの接続を閉じる必要があります。
バックグラウンド タスクのトリガーを開始する DeviceUseTrigger オブジェクトの RequestAsync メソッドを呼び出し、バックグラウンド タスクが正常に開始されたかどうかを判断するために使用した RequestAsync から DeviceTriggerResults オブジェクトを返します。
Note
Windows は、必要なタスク開始ポリシー確認がすべて完了していることを確認します。 すべてのポリシー確認が完了すると、更新操作が Microsoft Store アプリの外部でバックグラウンド タスクとして実行され、操作の進行中にアプリを安全に中断できるようになります。 Windows はランタイム要件も適用し、それらの要件が満たされなくなった場合はバックグラウンド タスクを取り消します。
StartSyncBackgroundTaskAsync から返された DeviceTriggerResults オブジェクトを使用して、バックグラウンド タスクが正常に開始されたかどうかを判断します。 switch ステートメントは、DeviceTriggerResults からの結果を検査するために使用されます。
- デバイスのバックグラウンド タスクからの進行状況をアプリ UI に反映して更新するプライベート OnSyncWithDeviceProgress イベント ハンドラーを実装します。
- バックグラウンド タスクが完了したときに、バックグラウンド タスクからフォアグラウンド アプリへの移行を処理するプライベート OnSyncWithDeviceCompleted イベント ハンドラーを実装します。
- BackgroundTaskCompletedEventArgs オブジェクトの CheckResults メソッドを使用して、バックグラウンド タスクによって例外がスローされたかどうかを判断します。
- アプリは、バックグラウンド タスクが完了すると、フォアグラウンド アプリで使用できるようにデバイスを再度開き、UI を更新してユーザーに通知します。
- UI からプライベート ボタン クリック イベント ハンドラーを実装して、バックグラウンド タスクを開始および取り消します。
- プライベート Sync_Click イベント ハンドラーは、前の手順で説明した SyncWithDeviceAsync メソッドを呼び出します。
- プライベート CancelSync_Click イベント ハンドラーは、プライベート CancelSyncWithDevice メソッドを呼び出してバックグラウンド タスクを取り消します。
- プライベート CancelSyncWithDevice メソッドは、BackgroundTaskRegistration オブジェクトで Unregister メソッドを使用してデバイスを再度開くことができるように、アクティブなデバイスの同期を登録解除して取り消します。
サンプルで確認する: Scenario7_Sync ファイルという名前のファイルを参照してください。 バックグラウンド クラスは、IoSyncBackgroundTask で実装されます。
Windows アプリ認定キットの実行
Windows アプリ認定キットを実行します。
推奨。 Windows アプリ認定キットを実行すると、アプリが Microsoft Store の要件を満たしていることを確認できます。 アプリに主要な機能を追加するたびに実行する必要があります。
関連するサンプル
UWP アプリ UI の設計についての詳細をご覧ください。
C# を使用した UWP アプリのロードマップと、C++ を使用した UWP アプリの Visual Basic とロードマップ
C++、C#、または Visual Basic を一般的に使用して UWP アプリを作成する方法について説明します。
アプリが長時間かかる可能性のある作業を行うとき、アプリの応答性を維持する方法について説明します。