快速入門:列舉常用的裝置 (HTML)
[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]
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 函式取得 selector 字串。接著應用程式會將這個值傳送到 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 取得 selector 字串,然後將 selector 傳送到 FindAllAsync。使用 selector 字串而不是 DeviceClass 列舉的程式碼,在 switch 陳述式的相關情況中會標記為註解。
後三個選項沒有 DeviceClass 列舉值,因此只會顯示取得適當 selector 字串的 API 呼叫。
5. 建置應用程式
在 [建置] 功能表中按一下 [建置方案]****,即可建置專案。
6. 測試應用程式
- 在 [偵錯] 功能表中按一下 [開始偵錯]**** 來測試方案。
- 選取要列舉的裝置介面類別。
- 按一下 [列舉] 按鈕,開始搜尋屬於指定裝置介面類別的裝置介面。應用程式會在它建立的頁面下半部列出裝置介面。
7. 新增您自己的裝置功能 (選用)
若要開始存取裝置功能而不是只列示裝置,請將您所列舉之裝置的 DeviceInformation.id 屬性傳送到 Windows 執行階段 API 以使用該裝置。例如,您可以使用列舉的網路攝影機識別碼來設定 Windows.Media.Capture.MediaCaptureInitializationSettings.VideoDeviceId 屬性,藉此指定用於擷取視訊的網路攝影機。
將所需的功能加入專案的 package.appxmanifest 檔案。
先從將裝置識別碼傳送到可以與裝置互動的 API 開始。部分方法會使用裝置識別碼來初始化物件以使用裝置:
- Windows.Media.Capture.MediaCaptureInitializationSettings.AudioDeviceId
- Windows.Media.Capture.MediaCaptureInitializationSettings.VideoDeviceId
- Windows.Devices.Portable.StorageDevice.FromId
- Windows.Devices.Sms.SmsDevice.FromIdAsync
- Windows.Networking.Proximity.ProximityDevice.FromId
對於使用 MTP 裝置服務的 WPD 裝置 (使用 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 取得的 selector 字串,傳遞到 findAllAsync。
如果您想要的裝置介面類別不在 Windows.Device.Enumeration.DeviceClass 列舉中,就沒有 Windows 執行階段 API 可以為您取得 selector 字串,您必須自己建置進階查詢語法 (AQS) 字串,然後將它傳遞到 findAllAsync。
若要為指定類型的可用裝置建立查詢,您必須知道裝置類別 GUID。這裡的程式碼包含使用者在輸入方塊中輸入的 GUID 指定之裝置介面類別的可用裝置的查詢。GUID 的格式必須是 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"。
注意 確定 GUID 在 selector 字串中是以括號括住。例如,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 來列舉裝置並取得裝置通知。
相關主題
為列舉提供 selector 字串的 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
建立 selector 字串的進階查詢語法 (AQS)