Перечисление устройств

API-интерфейсы Windows.Devices.Enumeration позволяют находить устройства, которые подключены к системе, подключены извне или обнаруживаются по беспроводным или сетевым протоколам.

Примеры

Самый простой способ перечислить все доступные устройства — snapshot с помощью команды FindAllAsync (описано далее в разделе ниже).

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

Более сложный пример API Windows.Devices.Enumeration см. в разделе Пример перечисления и связывания устройств.

Интерфейсы API перечисления

Пространство имен Windows.Devices.Enumeration позволяет находить устройства, которые внутренне подключены к системе, подключены извне или обнаруживаются по беспроводным или сетевым протоколам. Ниже перечислены некоторые функции, поддерживаемые этими API.

  • Поиск устройства для подключения с помощью вашего приложения.
  • Получение информации об устройствах, подключенных или обнаруженных системой.
  • Получение приложением уведомлений о добавлении, подключении, отключении, изменении состояния или других свойств устройств.
  • Получение приложением фоновых триггеров о подключении, отключении, изменении состояния или других свойств устройств.

Эти API могут перечислять устройства по любому из следующих протоколов и шин ниже при условии, что конкретное устройство и система, в которой работает приложение, поддерживают соответствующую технологию. Этот список не является исчерпывающим, и конкретное устройство может поддерживать другие протоколы.

Во многих случаях вам незачем беспокоиться об использовании API перечисления. Это связано с тем, что многие интерфейсы API, использующие устройства, автоматически выбирают подходящее устройство по умолчанию или предоставляют упрощенный API перечисления. Например, MediaElement автоматически использует устройство обработки звука по умолчанию. Если ваше приложение может использовать устройство по умолчанию, нет необходимости использовать в нем API перечисления. API перечисления предоставляют универсальный гибкий способ обнаружения доступных устройств и соединения с ними. В этом разделе представлены сведения о перечислении устройств и четыре стандартных способа перечисления.

  • Применение пользовательского интерфейса DevicePicker
  • Перечисление снимка устройств, которые могут быть обнаружены системой в текущий момент
  • Перечисление устройств, которые могут быть обнаружены в текущий момент, и ожидание изменений
  • Перечисление устройств, которые могут быть обнаружены в текущий момент, и ожидание изменений в фоновой задаче

Объекты DeviceInformation

При работе с API перечисления часто приходится использовать объекты DeviceInformation. Эти объекты содержат большинство доступных сведений об устройстве. В таблице ниже описаны некоторые свойства DeviceInformation, которые вам пригодятся. Полный список см. на странице со справочной документацией по DeviceInformation.

Свойство Комментарии
DeviceInformation.Id Это уникальный идентификатор устройства в виде строковой переменной. В большинстве случаев вы будете просто передавать это непрозрачное значение от одного метода к другому, чтобы указать конкретное устройство, которое вам необходимо. Это свойство и свойство DeviceInformation.Kind также можно использовать после закрытия приложения и его повторного открытия. Это гарантирует, что вы сможете восстановить и повторно использовать тот же самый объект DeviceInformation.
DeviceInformation.Kind Указывает вид объекта устройства, представленного объектом DeviceInformation. Это не категория или тип устройства. Одно устройство может быть представлено несколькими различными объектами DeviceInformation разных видов. Возможные значения этого свойства и их взаимосвязи приводятся в разделе DeviceInformationKind.
DeviceInformation.Properties Этот контейнер свойств содержит сведения, запрашиваемые для объекта DeviceInformation. На наиболее распространенные свойства можно легко ссылаться как на свойства объекта DeviceInformation, например DeviceInformation.Name. Дополнительные сведения см. в статье Свойства сведений об устройстве.

 

Пользовательский интерфейс DevicePicker

DevicePicker — это элемент управления, предоставляемый Windows, который создает небольшой пользовательский интерфейс, чтобы пользователь мог выбирать устройство из списка. Его можно настроить несколькими способами, например:

  • Управление устройствами, отображаемыми в пользовательском интерфейсе, путем добавления SupportedDeviceSelectors, SupportedDeviceClasses или и того, и другого в DevicePicker.Filter. В большинстве случаев требуется добавить только один селектор или класс, но если вам нужно больше, вы можете добавить несколько элементов. Если вы добавляете несколько селекторов или классов, они соединяются с помощью функции логики ИЛИ.
  • Укажите свойства, которые требуется получить для устройств. Для этого добавьте свойства в DevicePicker.RequestedProperties.
  • Измените внешний вид DevicePicker с помощью функции Внешний вид.
  • Укажите размер и расположение объекта DevicePicker при его отображении.

При отображении элемента DevicePicker произойдет автоматическое обновление содержимого пользовательского интерфейса, если устройства добавляются, удаляются или обновляются.

Примечание Нельзя указать DeviceInformationKind с помощью DevicePicker. Если вам необходимы устройства определенного вида DeviceInformationKind, вам понадобится создать объект DeviceWatcher и предоставить собственный пользовательский интерфейс.

 

Если вы захотите использовать трансляцию мультимедийного содержимого и DIAL, то они также имеют собственные средства выбора. Это CastingDevicePicker и DialDevicePicker, соответственно.

Перечисление снимка устройств

В некоторых сценариях DevicePicker может не подойти для ваших потребностей, и вам понадобится что-то более универсальное. Возможно, вы хотите создать собственный пользовательский интерфейс или перечислить устройства без отображения интерфейса для пользователя. В таких случаях можно перечислить снимок устройств. Для этого вы просматриваете устройства, которые в данный момент подключены к системе или связаны с ней. Однако следует помнить, что этот метод анализирует только снимок доступных устройств, поэтому вы не сможете обнаружить устройства, подключаемые после получения перечисления. Вы также не будете получать уведомления об обновлении или удалении устройства. Другим потенциальным недостатком, о котором следует упомянуть, является то, что данный метод удерживает все результаты до полного завершения перечисления. По этой причине не следует использовать данный метод, если требуется получить объекты AssociationEndpoint, AssociationEndpointContainer или AssociationEndpointService, поскольку они определяются по протоколу проводной или беспроводной связи. Этот процесс может занять до 30 секунд. В этом случае для перечисления возможных устройств необходимо использовать объект DeviceWatcher.

Чтобы выполнить перечисление посредством снимка устройств, используйте метод FindAllAsync. Этот метод ждет, пока весь процесс перечисления не будет завершен, и возвращает все результаты как один объект DeviceInformationCollection. Этот метод также перегружен и имеет несколько параметров для фильтрации результатов и выделения из них только нужных устройств. Для этого нужно предоставить значение DeviceClass или передать средство выбора устройств. Селектор устройства — это строка расширенного синтаксиса запросов (AQS), которая указывает устройства, которые требуется перечислить. Подробнее: Создание средства выбора устройств.

Помимо ограничения результатов, также можно указать, какие свойства устройств необходимо получить. В этом случае указанные свойства будут доступны в контейнере свойств для каждого из объектов DeviceInformation, возвращаемых в коллекцию. Важно помнить, что не все свойства доступны для всех видов устройств. Чтобы узнать, какие свойства доступны для тех или иных типов устройств, изучите раздел Свойства сведений об устройстве.

Перечисление и отслеживание устройств

Более мощным и гибким способом перечисления устройств является создание объекта DeviceWatcher. Этот вариант обеспечивает максимальную гибкость при перечислении устройств. Он позволяет перечислять устройства, присутствующие в настоящий момент, а также получать уведомления при добавлении и удалении устройств, которые соответствуют параметрам средства выбора устройств, а также при изменении свойств устройств. При создании DeviceWatcher вы предоставляете средство выбора устройств. Подробнее о средствах выбора устройств: Создание средства выбора устройств. После создания наблюдателя вы будете получать следующие уведомления для любого устройства, которое соответствует указанным критериям.

  • Уведомление о добавлении устройства.
  • Уведомление об обновлении, если отслеживаемое свойство изменяется.
  • Уведомление об удалении, если устройство больше недоступно или не соответствует вашему фильтру.

В большинстве случаев использования DeviceWatcher вы храните список устройств и добавляете, удаляете или обновляете его элементы по мере того, как наблюдатель получает обновления от отслеживаемых устройств. При получении уведомления об обновлении измененная информация будет доступна как объект DeviceInformationUpdate. Чтобы обновить список устройств, сначала найдите соответствующий измененный объект DeviceInformation. Затем вызовите метод Update для этого объекта, предоставив объект DeviceInformationUpdate. Это удобная функция, которая автоматически обновляет объект DeviceInformation.

Поскольку DeviceWatcher рассылает уведомления при добавлении и изменении устройств, рекомендуется использовать этот метод перечисления устройств, если вас интересуют объекты AssociationEndpoint, AssociationEndpointContainer или AssociationEndpointService, так как они перечисляются по сетевым или беспроводным протоколам.

Для создания объекта DeviceWatcher используйте один из методов CreateWatcher. Эти методы перегружены, что предоставляет возможность указать требуемые устройства. Для этого нужно предоставить значение DeviceClass или передать средство выбора устройств. Средство выбора устройств — это строка AQS, определяющая устройства для перечисления. Подробнее: Создание средства выбора устройств. Вы также можете задать свойства устройств, которые требуется получить. В этом случае указанные свойства будут доступны в контейнере свойств для каждого из объектов DeviceInformation, возвращаемых в коллекцию. Важно помнить, что не все свойства доступны для всех видов устройств. Чтобы узнать, какие свойства доступны для каких типов устройств, см. статью Свойства сведений об устройстве.

Наблюдение за устройствами как фоновая задача

Отслеживание устройств в фоновой задаче очень похоже на создание DeviceWatcher, рассмотренное выше. К слову, вам все равно придется сначала создать обычный объект DeviceWatcher, как описано в предыдущем разделе. После его создания вызовите GetBackgroundTrigger вместо DeviceWatcher.Start. При вызове метода GetBackgroundTrigger необходимо определить, какие из уведомлений вас интересуют: уведомления о добавлении, удалении или обновлении. Невозможно запросить обновление или удаление, не запросив также и добавление. После регистрации триггера объект DeviceWatcher сразу же начнет свою работу в фоновом режиме. С этого момента при получении нового уведомления для вашего приложения, которое соответствует заданным условиям, активируется фоновая задача, которая предоставит вам последние изменения с момента последней активации вашего приложения.

Важно Впервые DeviceWatcherTrigger активирует приложение, когда наблюдатель достигнет состояния EnumerationCompleted . Это означает, что он будет содержать все исходные результаты. При последующей активации приложения он будет содержать только уведомления о добавлении, обновлении и удалении, полученные с момента последней активации. Это немного отличается от объекта переднего плана DeviceWatcher, так как исходные результаты поступают не по одному, а только пакетом после перехода в состояние EnumerationCompleted.

 

Некоторые беспроводные протоколы ведут себя по-другому, если ведут сканирование не в приоритетном, а фоновом режиме; они также могут совсем не поддерживать сканирование в фоновом режиме. Существует три варианта относительно возможности фонового сканирования. В следующей таблице перечислены возможности и их последствия для приложения. Например, Bluetooth и Wi-Fi Direct не поддерживают фоновое сканирование, поэтому они не поддерживают DeviceWatcherTrigger.

Поведение Влияние
Такое же поведение в фоновом режиме Нет
В фоновом режиме возможно только пассивное сканирование Для обнаружения устройства может потребоваться больше времени из-за ожидания пассивного сканирования.
Фоновое сканирование не поддерживается С помощью DeviceWatcherTrigger не будут обнаруживаться никакие устройства, уведомления об обновлении не будут отправляться.

 

Если DeviceWatcherTrigger использует протокол, который не поддерживает сканирование в качестве фоновой задачи, ваш триггер все же будет работать. Однако вы не сможете получать обновления или результаты по этому протоколу. Обновления для других протоколов и устройств будут по-прежнему работать нормально.

Использование DeviceInformationKind

В большинстве сценариев вам незачем беспокоиться о виде DeviceInformationKind объекта DeviceInformation. Это связано с тем, что средство выбора устройств, возвращаемое используемым API устройства, во многих случаях гарантирует получение правильных видов объектов устройств для использования с соответствующими API. Однако в некоторых сценариях вам может потребоваться получить DeviceInformation для устройств, притом что соответствующий API устройства для предоставления средства выбора устройств отсутствует. В этом случае вам потребуется создать собственное средство выбора. Например, у Web Services on Devices нет специализированного API, но вы можете обнаружить эти устройства и получить информацию о них с помощью API Windows.Devices.Enumeration, а затем использовать их с помощью API сокетов.

Если вы создаете собственное средство выбора устройств для перечисления объектов устройств, необходимо тщательно изучить DeviceInformationKind. Все возможные виды, а также их взаимосвязи описаны на странице справки для DeviceInformationKind. Один из самых распространенных способов использования DeviceInformationKind — определение вида устройств, которые вы ищете, при отправке запроса вместе со средством выбора устройств. Таким образом вы будете уверены, что перечисляете только те устройства, которые соответствуют указанному виду DeviceInformationKind. Например, вы можете найти объект DeviceInterface, а затем выполнить запрос, чтобы получить сведения для родительского объекта Device. Этот родительский объект может содержать дополнительные сведения.

Важно отметить, что свойства, доступные в контейнере свойств объекта DeviceInformation, могут отличаться в зависимости от значения DeviceInformationKind устройства. Некоторые свойства доступны только для определенных видов. Подробнее о том, какие свойства доступны для каких видов, см. в разделе Свойства сведений об устройстве. Следовательно, в примере выше поиск родительского элемента Device даст доступ к дополнительным сведениям, которые не были доступны из объекта устройства DeviceInterface. Поэтому когда вы создаете строки фильтра AQS, запрошенные свойства должны быть доступны для перечисляемых объектов DeviceInformationKind. Подробнее о создании фильтра: Создание средства выбора устройств.

Перечисление объектов AssociationEndpoint, AssociationEndpointContainer или AssociationEndpointService происходит по сетевому или беспроводному протоколу. В таких случаях вместо FindAllAsync рекомендуется использовать CreateWatcher. Дело в том, что при поиске по сети время ожидания операций поиска может достигать 10 и более секунд, прежде чем будет получено событие EnumerationCompleted. FindAllAsync будет работать до тех пор, пока не активируется событие EnumerationCompleted. Если вы используете DeviceWatcher, вы получите результаты, которые будут ближе к реальному времени, вне зависимости от того, когда вызывается событие EnumerationCompleted.

Сохранение устройства для использования в будущем

Любой объект DeviceInformation однозначно определяется сочетанием двух параметров: DeviceInformation.Id и DeviceInformation.Kind. Если сохранить эти два значения, то можно будет воссоздать утерянный объект DeviceInformation, передав их в метод CreateFromIdAsync. В этом случае вы сможете сохранить настройки пользователя для устройства, которое интегрируется с вашим приложением.