列舉裝置

Windows.Devices.Enumeration API 可讓您尋找內部連接到系統、外部連接或者可透過無線或網路通訊協定偵測到的裝置。

範例

列舉所有可用裝置的最簡單方法是使用 FindAllAsync 命令拍攝快照 (將在下節中進一步說明)。

async void enumerateSnapshot(){
  DeviceInformationCollection collection = await DeviceInformation.FindAllAsync();
}

有關 Windows.Devices.Enumeration API 的更進階範例,請參閱裝置列舉和配對範例

列舉 API

Windows.Devices.Enumeration 命名空間可讓您來尋找內部連接到系統、外部連接或者可透過無線或網路通訊協定偵測到的裝置。 這些 API 支援的部分功能包括:

  • 尋找要連接到您應用程式的裝置。
  • 取得連接到系統或可由系統探索之裝置的資訊。
  • 讓應用程式在新增、連線、中斷連線、變更線上狀態或變更其他屬性時接收通知。
  • 讓應用程式在裝置連線、中斷連線、變更線上狀態或變更其他屬性時接收背景觸發程序。

這些 API 可以透過以下任何通訊協定和匯流排列舉裝置,前提是執行應用程式的單一裝置和系統支援該技術。 這並非詳盡的清單,特定裝置可能支援其他通訊協定。

在大多數情況下,您無需擔心使用列舉 API。 這是因為許多使用裝置的 API 會自動選擇合適的預設裝置或提供更精簡的列舉 API。 例如,MediaElement 將自動使用預設的音訊轉譯器裝置。 只要您的應用程式可以使用預設裝置,就無需在應用程式中使用列舉 API。 列舉 API 為您提供了一種通用且靈活的方式,可探索並連接到可用裝置。 本主題提供有關列舉裝置的資訊,並描述列舉裝置的四種常見方法。

  • 使用 DevicePicker UI
  • 列舉系統目前可探索之裝置的快照
  • 列舉目前可發現的裝置並觀察變化
  • 列舉目前可發現的裝置,並觀察背景工作的變化

DeviceInformation 物件

使用列舉 API 時,您將經常需要使用 DeviceInformation 物件。 這些物件包含有關裝置的大部分可用資訊。 下表解釋了您可能感興趣的一些 DeviceInformation 屬性。 有關完整清單,請參閱 DeviceInformation 的參考頁。

屬性 註解
DeviceInformation.Id 這是裝置的唯一識別碼,以字串變數的形式提供。 在大多數情況下,這是一個不透明的值,您只需從一種方法傳遞到另一種方法即可指示您感興趣的特定裝置。 關閉應用程式並重新開啟它後,您還可以使用此屬性和 DeviceInformation.Kind 屬性。 這將確保您可以恢復並重複使用相同的 DeviceInformation 物件。
DeviceInformation.Kind 這指示由 DeviceInformation 物件表示之裝置物件的類型。 這不是裝置類別或裝置類型。 單一裝置可以由不同種類的多個不同 DeviceInformation 物件表示。 DeviceInformationKind 中列出了該屬性的可能值,以及它們之間的相互關係。
DeviceInformation.Properties 此屬性包包含 DeviceInformation 物件要求的資訊。 最常見的屬性可以輕鬆參考為 DeviceInformation 物件的屬性,例如使用 DeviceInformation.Name。 如需詳細資訊,請參閱裝置資訊屬性

 

DevicePicker 使用者介面

DevicePicker 是 Windows 提供的一個控制項,它會建立一個小型 UI,讓使用者能夠從清單中選擇裝置。 其可以透過多種方式進行自訂,例如:

顯示 DevicePicker 時,如果新增、移除或更新裝置,UI 的內容將自動更新。

注意 您無法使用 DevicePicker 指定 DeviceInformationKind。 如果您想要擁有特定 DeviceInformationKind 的裝置,您將需要建置 DeviceWatcher 並提供您自己的 UI。

 

如果您想使用投射媒體內容和 DIAL,它們也各自提供了自己的選取器。 它們分別是 CastingDevicePickerDialDevicePicker

列舉裝置快照

在某些情況下,DevicePicker 可能無法滿足您的需求,您會需要更靈活的東西。 也許您想要建立自己的 UI,或需要列舉裝置而不向使用者顯示 UI。 在以下情況,您可以列舉裝置的快照。 這涉及查看目前連接到系統或與系統配對的裝置。 但是,您需要注意,此方法僅查看可用裝置的快照,因此您在列舉清單後將無法找到已連接的裝置。 如果裝置已更新或移除,您也不會收到通知。 需要注意的另一個潛在缺點是,此方法將保留所有結果,直到整個列舉完成。 因此,當您對 AssociationEndpointAssociationEndpointContainerAssociationEndpointService 物件感興趣時,不應使用此方法,因為它們是透過網路或無線通訊協定找到的。 這最多可能需要 30 秒才能完成。 在這種情況下,您應該使用 DeviceWatcher 物件來列舉可能的裝置。

若要列舉裝置快照,請使用 FindAllAsync 方法。 此方法會等待整個列舉過程完成,並將所有結果作為 DeviceInformationCollection 物件傳回。 此方法也會多載,為您提供了多個選項來篩選結果,並將其限制為您感興趣的裝置。 您可以透過提供 DeviceClass 或傳入裝置選取器來完成此作業。 裝置選取器是進階查詢語法 (AQS) 字串,用於指定要列舉的裝置。 如需詳細資訊,請參閱建置裝置選取器

除了限制結果之外,您還可以指定要為裝置擷取的屬性。 如果這樣做,則在集合中傳回的每個 DeviceInformation 物件的屬性包中皆會有指定的屬性。 請務必注意,並非所有屬性都適用於所有裝置類型。 若要查看哪些屬性可用於哪些裝置類型,請參閱裝置資訊屬性

列舉和監視裝置

一種更強大、更靈活的裝置列舉方法是建立 DeviceWatcher。 當您列舉裝置時,此選項可提供最大的靈活性。 它可讓您列舉目前存在的裝置,並在新增、移除與您的裝置選取器相符的裝置或屬性變更時接收通知。 建立 DeviceWatcher 時,您需要提供一個裝置選取器。 如需裝置選取器的詳細資訊,請參閱建置裝置選取器。 建立監看器後,您將收到以下任何符合所提供條件之裝置的通知。

  • 新增裝置時新增通知。
  • 當您感興趣的屬性發生變更時更新通知。
  • 當裝置不再可用或不再與您的篩選器相符時,移除通知。

在大多數情況下,您使用 DeviceWatcher 時,會維護裝置清單並在其中新增、移除項目,或在您的監看器從您正在監視的裝置接收更新時更新項目。 當您收到更新通知時,更新的資訊將作為 DeviceInformationUpdate 物件提供。 若要更新您的裝置清單,請先找到已變更的相應 DeviceInformation。 然後呼叫該物件的 Update 方法,並提供 DeviceInformationUpdate 物件。 這是一個很方便的函式,將自動更新您的 DeviceInformation 物件。

由於 DeviceWatcher 在裝置到達和變更時發送通知,因此當您對 AssociationEndpointAssociationEndpointContainerAssociationEndpointService 物件感興趣時,您應該使用此列舉裝置的方法,因為它們是透過網路或無線通訊協定列舉的。

若要建立 DeviceWatcher,請使用 CreateWatcher 方法之一。 這些方法已經多載,可讓您能夠指定您感興趣的裝置。 您可以透過提供 DeviceClass 或傳入裝置選取器來完成此作業。 裝置選取器是 AQS 字串,用於指定要列舉的裝置。 如需詳細資訊,請參閱建置裝置選取器。 您也可以指定要擷取裝置且感興趣的屬性。 如果這樣做,則在集合中傳回的每個 DeviceInformation 物件的屬性包中皆會有指定的屬性。 請務必注意,並非所有屬性都適用於所有裝置類型。 若要查看哪些屬性可用於哪些裝置類型,請參閱裝置資訊屬性

以背景工作的形式監看裝置

將監看裝置當做背景工作與上述建立 DeviceWatcher 的流程非常類似。 事實上,您仍然需要先建立一個普通的 DeviceWatcher 物件,如上一節所述。 建立後,請呼叫 GetBackgroundTrigger 而不是 DeviceWatcher.Start。 當您呼叫 GetBackgroundTrigger 時,您必須指定感興趣的通知:新增、移除或更新。 如果不要求新增,則無法要求更新或移除。 註冊觸發程序後,DeviceWatcher 將立即開始在背景執行。 從現在開始,每當它收到符合您的條件的應用程式的新通知時,背景工作就會觸發,並為您提供自上次觸發您的應用程式以來的最新變更。

重要事項DeviceWatcherTrigger 第一次觸發您的應用程式是在監看器達到 EnumerationCompleted 狀態時。 這代表它將包含所有初始結果。 以後任何時候它觸發您的應用程式時,它只會包含自上次觸發以來發生的新增、更新和移除通知。 這與前景 DeviceWatcher 物件略有不同,因為初始結果不會一次出現一個,並且僅在達到 EnumerationCompleted 後才以組合形式傳遞。

 

某些無線通訊協定在背景掃描與前景掃描時的行為有所不同,或者它們可能根本不支援背景掃描。 有與背景掃描相關的三種可能性。 下表列出了可能性,以及這可能對您的應用程式產生的影響。 例如,藍牙和 Wi-Fi Direct 不支援背景掃描,因此根據擴充,它們也不支援 DeviceWatcherTrigger

行為 影響
背景中的相同行為
在背景中只能進行被動掃描 在等待被動掃描發生時,裝置可能需要更長時間才能發現。
不支援背景掃描 DeviceWatcherTrigger 無法偵測到任何裝置,也不會回報任何更新。

 

如果您的 DeviceWatcherTrigger 包含不支援掃描作為背景工作的通訊協定,您的觸發程序仍然可以運作。 不過,您將無法透過該通訊協定取得任何更新或結果。 其他通訊協定或裝置的更新仍將會正常偵測到。

使用 DeviceInformationKind

在大部分情況下,您不需要擔心 DeviceInformation 物件的 DeviceInformationKind。 這是因為您正在使用的裝置 API 傳回的裝置選取器通常會保證您能獲得正確類型的裝置物件,以與其 API 一起使用。 但在某些情況下,您可能會想要取得裝置的 DeviceInformation,但沒有對應的裝置 API 來提供裝置選取器。 在這些情況下,您將需要建立自己的選取器。 例如,裝置上的 Web 服務沒有專用 API,但您可以使用 Windows.Devices.Enumeration API 發現這些裝置並取得其相關資訊,然後使用通訊端 API 使用它們。

如果您要建置自己的裝置選取器來列舉裝置物件,那麼您必須要了解 DeviceInformationKindDeviceInformation Kind 的參考頁上描述了所有可能的類型,以及它們之間的關係。 DeviceInformationKind 最常見的用途之一是在與裝置選取器一起提交查詢時,指定要搜尋的裝置類型。 透過這樣做,它可以確保您僅列舉符合所提供 DeviceInformationKind 的裝置。 例如,您可以找到 DeviceInterface 物件,然後執行查詢以取得父 Device 物件的資訊。 該父物件可能包含其他資訊。

需要注意的是,DeviceInformation 物件的屬性包中可用的屬性將根據裝置的 DeviceInformationKind 而有所不同。 某些屬性僅適用於某些類型。 有關哪些屬性可用於哪些類型的詳細資訊,請參閱裝置資訊屬性。 因此,在上面的範例中,搜尋父 Device 將使您能夠存取 DeviceInterface 裝置物件中無法取得的更多資訊。 因此,當您建立 AQS 篩選器字串時,請確保所要求的屬性可用於您正在列舉的 DeviceInformationKind 物件非常重要。 如需建置篩選的詳細資訊,請參閱建置裝置選取器

當您列舉 AssociationEndpointAssociationEndpointContainerAssociationEndpointService 物件時,您是透過無線或網路通訊協定進行列舉。 在這些情況下,建議您不要使用 FindAllAsync,而是使用 CreateWatcher。 這是因為透過網路搜尋通常會導致搜尋作業在產生 EnumerationCompleted 之前不會逾時 10 秒或更長時間。 FindAllAsync 在觸發 EnumerationCompleted 之前不會完成其作業。 如果您使用 DeviceWatcher,則無論何時呼叫 EnumerationCompleted,您都會取得更接近即時的結果。

儲存裝置以供稍後使用

所有 DeviceInformation 物件都是由兩個訊息的組合唯一識別碼:DeviceInformation.IdDeviceInformation.Kind。 如果保留這兩個訊息,則可以在遺失後透過將此資訊提供給 CreateFromIdAsync 來重新建立 DeviceInformation 物件。 如果您這麼做,則可以儲存與您的應用程式整合之裝置的使用者喜好設定。