Share via


快速入门:枚举常用设备 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

Windows.Devices.Enumeration 命名空间提供枚举设备的两种方法:FindAllAsyncCreateWatcherFindAllAsync 对可用设备执行一次性搜索,它最适合在用户添加、删除或更改设备时不需要更新的应用。 当用户在操作系统完成初始枚举后添加、删除或更改设备时 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。这等同于从与设备类型相关联的 Windows 运行时 API 获取选择器字符串,然后将选择器传递给 FindAllAsync。在 switch 语句中的相关情形内会注释掉使用选择器字符串而不是 DeviceClass 枚举的代码。

对于最后三个选项,不存在任何 DeviceClass 枚举值,因此仅会显示获取相应的选择器字符串的 API 调用。

 

5. 生成应用

在“生成”菜单上,单击“生成解决方案”****生成项目。

6. 测试应用

  1. 在“调试”菜单上,单击“启动调试”****测试该解决方案。
  2. 选取要枚举的设备接口类。
  3. 单击“枚举”按钮以开始搜索属于指定设备接口类的设备接口。应用会在设备接口所创建页的下半部分中列出这些设备接口。

7. 添加你自己的设备功能(可选)

若要开始访问设备功能而不仅仅是列出设备,请将你已枚举的设备的 DeviceInformation.id 属性传递给 Windows 运行时 API 以使用该设备。例如,你可以使用已枚举的摄像头的 ID 来设置Windows.Media.Capture.MediaCaptureInitializationSettings.VideoDeviceId 属性,以指定摄像头用于视频捕获。

  1. 将你需要的功能添加到项目的 package.appxmanifest 文件。

  2. 通过将设备 ID 传递给你可以用于与设备进行交互的 API 来开始。存在一些采用设备 ID 来初始化对象以使用设备的方法。

    对于使用 MTP 设备服务的 WPD 设备(已使用 Windows.Devices.Portable.ServiceDevice.GetDeviceSelectorWindows.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 枚举内,且不存在任何 Windows 运行时 API 来为你获取选择器,那么你将必须自己生成一个高级查询语法 (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 以便可以枚举设备和获得设备通知。

 

如何以动态方式枚举

相关主题

为枚举提供选择器字符串的 Windows 运行时 API

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)

以编程方式使用高级查询语法