Краткое руководство: перечисление часто используемых устройств (HTML)

[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]

Пространство имен Windows.Devices.Enumeration предлагает два метода перечисления устройств: FindAllAsync и CreateWatcher. FindAllAsync выполняет однократный поиск доступных устройств и лучше всего подходит для приложений, не требующих обновления при добавлении, удалении или изменении устройств пользователем. CreateWatcher перечисляет устройства и порождает события уведомления, когда пользователь добавляет, удаляет или изменяет устройства после того, как операционная система завершила начальное перечисление. Здесь мы расскажем о том, как выполнить однократное перечисление часто используемых устройств с помощью FindAllAsync.

Цель: Для создания списков доступных устройств стандартных категорий используется пространство имен Windows.Devices.Enumeration.

Необходимые условия

Вы должны знать JavaScript и HTML.

Время для завершения: 20 мин.

Инструкции

1. Открытие Microsoft Visual Studio

Откройте экземпляр программы Visual Studio.

2. Создание нового проекта

В диалоговом окне Создать проект выберите тип проекта JavaScript и "Пустое приложение".

3. Вставка HTML-кода приложения

Откройте Default.html и скопируйте этот код в файл, заменив его содержимое.

Этот HTML-код предоставляет пользовательский интерфейс, позволяющий выбрать для перечисления один из семи типов устройств: микрофоны, воспроизведение звука, веб-камеры, съемные носители, службы устройств MTP, устройства SMS и устройства близкого взаимодействия.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script src="/js/default.js"></script>
</head>
<body data-design-activate="defaultPage.activated">
    <h1>Device Enumeration Sample</h1>

    <h2 >Input</h2>

    <div>            

        <div id="Input">
           <p>This scenario demonstrates using the device enumeration API
              to look for specific device interfaces. A device interface
              is the programmatic entry point for a device.</p>
           <p>Select a device interface class</p>
                <select id="SelectInterfaceClass" size="7" >
                    <option value="audioCapture">Audio Capture</option>
                    <option value="audioRender">Audio Playback</option>
                    <option value="videoCapture">Webcams</option>
                    <option value="portableStorageDevice">Portable Storage</option>
                    <option value="mtpService">MTP Device Service</option>
                    <option value="sms">SMS Device</option>
                    <option value="proximity">Proxmity Device</option>
                </select>
                <br />
                <p>Clicking the enumerate button will start a search for 
                 device interfaces that belong to the specified device interface class. 
                 The device interfaces will be listed below.</p>
          <input onclick="onEnumerateDeviceInterfaces()" type="button" value="Enumerate" />
                <br /><br />
            </div>
    </div>


    <h2> Output</h2>

            <div id="statusMessage"></div>

            <!-- Device Enumeration results are displayed in this element -->
            <div  id="Output"></div>
</body>
</html>

4. Вставка кода JavaScript приложения

Откройте файл Default.js и вставьте следующий код.

В зависимости от выбранного пользователем типа устройства функция onEnumerateDeviceInterface выбирает значение DeviceClass или получает строку селектора от функции getDeviceSelector. Затем программа передает это значение в FindAllAsync. Если перечисление завершено успешно, функция successCallback выводит информацию об устройстве. В противном случае функция errorCallback выводит сообщение об ошибке.

function onEnumerateDeviceInterfaces() {
    document.getElementById("Output").innerHTML = ""; // clear output
    try {
        var selection = document.getElementById("SelectInterfaceClass");
        var selectedDeviceClass = 
            selection.options[selection.selectedIndex].value;
        var deviceClass;
        var Enumeration = Windows.Devices.Enumeration;
        var selectorString = "";

        var mtpServiceDevice = Windows.Devices.Portable.ServiceDevice;
        var smsDevice = Windows.Devices.Sms.SmsDevice;
        var proximityDevice = Windows.Networking.Proximity.ProximityDevice;
        switch (selectedDeviceClass) {
            case "audioCapture":
                // same as:
                // var mediaDevice = Windows.Media.Devices.MediaDevice;
                // selectorString =  mediaDevice.getAudioCaptureSelector();
                deviceClass = Enumeration.DeviceClass.audioCapture;
                break;
            case "audioRender":
                // same as:
                // var mediaDevice = Windows.Media.Devices.MediaDevice;
                // selectorString =  mediaDevice.getAudioRenderSelector();
                deviceClass = Enumeration.DeviceClass.audioRender;
                break;
            case "portableStorageDevice":
                // same as: 
                // var storageDevice = Windows.Devices.Portable.StorageDevice;
                // selectorString = storageDevice.getDeviceSelector();
                deviceClass = Enumeration.DeviceClass.portableStorageDevice;
                break;
            case "videoCapture":
                // same as:
                // var mediaDevice = Windows.Media.Devices.MediaDevice;
                // selectorString =  mediaDevice.getVideoCaptureSelector();
                deviceClass = Enumeration.DeviceClass.videoCapture;
                break;
            case "mtpService":
            // Windows.Devices.Portable.ServiceDevice.getDeviceSelector
                selectorString = mtpServiceDevice.getDeviceSelector(Windows.Devices.Portable.ServiceDeviceType.calendarService);
                break;
            case "sms":
            // Windows.Devices.Sms.SmsDevice.getDeviceSelector
                selectorString = smsDevice.getDeviceSelector();
                break;
            case "proximity":
            // Windows.Networking.Proximity.ProximityDevice.getDeviceSelector
                selectorString = proximityDevice.getDeviceSelector();
                break;
            case "imageScanner":
            // same as:
            // var scannerDevice = Windows.Devices.Scanners.ImageScanner;
            // selectorString = scannerDevice.getDeviceSelector();
                deviceClass = Enumeration.DeviceClass.imageScanner;
                break;
            default: deviceClass = Enumeration.DeviceClass.all;
        }

        var DeviceInformation = Enumeration.DeviceInformation;
        if (selectorString == "") {
            DeviceInformation.findAllAsync(deviceClass).then(
                successCallback, 
                errorCallback
            );
        } else {
            DeviceInformation.findAllAsync(selectorString, null).then(
                successCallback, 
                errorCallback
            );
        }
    } catch (e) {
        document.getElementById("statusMessage").innerHTML = 
            "Failed to enumerate devices, error: " + e.message;
    }
}

// Handles successful completion of the findAllAsync method.
function successCallback(deviceInformationCollection) {
    var numDevices = deviceInformationCollection.length;
    document.getElementById("statusMessage").innerHTML = 
        numDevices + " device interface(s) found";
    if (numDevices) {
        for (var i = 0; i < numDevices; i++) {
            printFriendlyNameAndID(deviceInformationCollection[i], 
                document.getElementById("Output"));
        }
    } else {
        document.getElementById("statusMessage").innerHTML = "No devices found";
    }
}

// Handles an error completion of the findAllAsync method.
function errorCallback(e) {
    document.getElementById("statusMessage").innerHTML = 
        "Failed to find devices, error: " + e.message;
}

// Prints the friendly name of the device interface and its ID 
// The ID is the device interface path.
function printFriendlyNameAndID(deviceInterface, log) {

    // The name property is equivalent to System.ItemNameDisplay property
    log.innerHTML += "<h3>" + 
            deviceInterface.name + "<h3/>";
    log.innerHTML += "<p>Interface ID: " + deviceInterface.id;    
    log.innerHTML += "<p>Enabled: " + deviceInterface.isEnabled;
    
    log.innerHTML += "<br />";
}

Примечание  

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

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

 

5. Сборка приложения

Чтобы собрать проект, в меню Сборка выберите пункт Собрать решение.

6. Проверка приложения

  1. Чтобы проверить приложение, в меню Отладка выберите пункт Начать отладку.
  2. Выберите класс интерфейса устройства для перечисления.
  3. Чтобы начать поиск интерфейсов устройств указанного класса, нажмите кнопку Enumerate. Программа перечисляет интерфейсы устройств в нижней части созданной им страницы.

7. Добавление собственных функций устройств (не обязательно)

Чтобы не просто перечислить устройства, но и получить доступ к их функциям, передайте в API среды выполнения Windows свойство DeviceInformation.id устройства, включенного в перечисление. Например, вы можете задать для свойства Windows.Media.Capture.MediaCaptureInitializationSettings.VideoDeviceId ИД входящей в перечисление веб-камеры, чтобы использовать ее для видеозахвата.

  1. Добавьте нужные возможности в файл package.appxmanifest проекта.

  2. Сначала передайте ИД устройства API, который вы можете использовать для взаимодействия с устройством. Существует несколько методов получения ИД устройства, чтобы инициализировать объект для использования устройства.

    Для устройств WPD, использующих службу устройств MTP (перечисление посредством Windows.Devices.Portable.ServiceDevice.GetDeviceSelector или Windows.Devices.Portable.ServiceDevice.GetDeviceSelectorFromServiceId), вы можете создать объект автоматизации COM:

    deviceFactory = new ActiveXObject("PortableDeviceAutomation.Factory");

    var device = deviceFactory.getDeviceFromId(deviceId);

Краткая сводка и дальнейшие действия

Вы научились перечислять стандартные типы устройств, передавая значение перечисления Windows.Device.Enumeration.DeviceClass или строку селектора, полученную от метода getDeviceSelector, в findAllAsync.

Если нужный класс интерфейса устройств отсутствует в перечислении Windows.Device.Enumeration.DeviceClass и если API среды выполнения Windows, от которого можно получить селектор, не существует, необходимо самостоятельно выполнить сборку строки с использованием дополнительного синтаксиса запроса (AQS) и передать ее в findAllAsync.

Чтобы создать запрос доступных устройств указанного типа, необходимо знать GUID класса устройств. Приведенный здесь фрагмент кода включает запрос доступных устройств, принадлежащих к классу интерфейсов устройств, который указан с помощью GUID, введенного пользователем в поле для ввода. GUID должен иметь формат "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".

Примечание  Убедитесь, что GUID в строке селектора заключен в кавычки. Например, var selectorString = "System.Devices.InterfaceClassGuid:=\"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\"";.

 

        if (textinput.value != ""){
            var textDeviceInterfaceClassGUID = textinput.value;
            var selectorString = "System.Devices.InterfaceClassGuid:=\"" + 
                textDeviceInterfaceClassGUID + 
                "\" AND System.Devices.InterfaceEnabled:=true";
            var Enum = Windows.Devices.Enumeration;
            Enum.DeviceInformation.findAllAsync(selectorString, null).then(
                    successCallback, 
                    errorCallback
                );

// Handles successful completion of the findAllAsync method.
function successCallback(deviceInformationCollection) {
    // Add your code here for processing the enumerated device collection.
}

// Handles an error completion of the findAllAsync method.
function errorCallback(e) {
    // Add your error-handling code here.
}

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

 

Динамическое перечисление

Связанные разделы

API среды выполнения Windows, предоставляющие строки селектора для перечисления

Windows.Media.Devices.MediaDevice.getAudioCaptureSelector

Windows.Media.Devices.MediaDevice.getAudioRenderSelector

Windows.Media.Devices.MediaDevice.getVideoCaptureSelector

Windows.Media.Devices.MediaDevice.getDefaultAudioRenderId

Windows.Media.Devices.MediaDevice.getDefaultAudioCaptureId

Windows.Devices.Portable.StorageDevice.GetDeviceSelector

Windows.Devices.Portable.ServiceDevice.GetDeviceSelector

Windows.Devices.Portable.ServiceDevice.GetDeviceSelectorFromServiceId

Windows.Devices.Sms.SmsDevice.GetDeviceSelector

Windows.Networking.Proximity.ProximityDevice.GetDeviceSelector

Дополнительный синтаксис запроса (AQS) для сборки строк селектора

Программное использование дополнительного синтаксиса запроса