Devices

Develop an app that's ready to connect to a wide range of wired and wireless devices that allow users to enjoy the mobility and flexibility of a Windows 8.1 device when they are enjoying or creating content at home or at work.

New or updated in Windows 8.1

  • Human Interface Device (HID) support
  • Point of Service (PoS) device support
  • USB device support
  • Bluetooth device support
  • 3D printer support
  • Scanning support

Human Interface Device (HID) support

[Get the Custom HID Device Access and Sample motion-sensor, firmware and Windows Runtime app for HID samples now.]

The Windows.Devices.HumanInterfaceDevice API lets your Windows Store app access devices that support the HID protocol.

When it was first developed, the protocol targeted devices like keyboards, mice, and joysticks. It was initially designed to run over the USB transport. Today the protocol supports a significantly larger set of devices. In addition, for Windows 8.1, Microsoft includes support for the USB, Bluetooth, Bluetooth LE, and I2C transports.

The new API is intended for two distinct audiences:

  1. The hardware partner who has created a HID peripheral and now needs a Windows Store app that lets Windows 8.1 users access or control that device. (Hardware partners can declare one app as automatically acquired when a user connects their peripheral.)

  2. The app developer who wants to create an app for one of these peripherals.

The hardware partner is already familiar with HID but needs to understand the requirements of Windows Store apps. The app developer will probably need to learn the protocol. If you are new to HID, see Introduction to HID Concepts in the HID driver documentation on MSDN.

But before you use the new API, review the Limitations section to find out whether your device falls within the supported categories.

Note  The target device for the following examples is the SuperMUTT, a test device that you can order from JJG Technologies.

Connecting to a HID

This code example shows how a Windows Store app, built with XAML and C#, uses the HidDevice.GetDeviceSelector method to create a selector for a specific HID device. Then the app uses the HidDevice.FromIdAsync method to open a connection to that device.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Windows.Devices.Enumeration;
using Windows.Devices.HumanInterfaceDevice;
using Windows.Storage;
using Windows.Storage.Streams;

namespace HidSampleCS
{
    class Enumeration
    {
        // Enumerate HID devices.
        private async void EnumerateHidDevices()
        {
            UInt32 vendorId = 0x045E;
            UInt32 productId = 0x078F;
            UInt32 usagePage = 0xFF00;
            UInt32 usageId = 0x0001;

            // Create a selector that gets a HID device using VID/PID and a 
            // VendorDefined usage.
            string selector = HidDevice.GetDeviceSelector(usagePage, usageId, 
                              vendorId, productId);

            // Enumerate devices using the selector.
            var devices = await DeviceInformation.FindAllAsync(selector);

            if (devices.Count > 0)
            {
                // Open the target HID device at index 0.
                HidDevice device = await HidDevice.FromIdAsync(devices.ElementAt(0).Id, 
                                   FileAccessMode.ReadWrite);

                // At this point the device is available to communicate with,
                // so we can send/receive HID reports from it or 
                // query it for control descriptions.
            }
            else
            {
                // There were no HID devices that met the selector criteria.
                this.NotifyUser("MUTT HID device not found");
            }
        }
    }
}

Retrieving data from a HID

Apps retrieve data from a HID device by using input reports. This example demonstrates how an app uses the HidInputReport.GetNumericControl method to retrieve a numeric value from a SuperMUTT device.

In the example, the connected HID device is represented by the DeviceList.Current.CurrentDevice object.

        private async Task GetNumericInputReportAsync()
        {
            var inputReport = await DeviceList.Current.CurrentDevice.GetInputReportAsync(SuperMutt.ReadWriteBuffer.ReportId);

            var inputReportControl = inputReport.GetNumericControl(SuperMutt.ReadWriteBuffer.NumericUsagePage, SuperMutt.ReadWriteBuffer.NumericUsageId);

            var data = inputReportControl.Value;

            rootPage.NotifyUser("Value read: " + data.ToString("X2", NumberFormatInfo.InvariantInfo), NotifyType.StatusMessage);
        }

Limitations of the HID API

Consider the following when considering implementation of this API set.

The Windows.Devices.HumanInterfacDevice API supports most HID devices. However, it blocks the top-level app collection represented by these usage pages:

  • HID_USAGE_PAGE_UNDEFINED
  • HID_USAGE_PAGE_GENERIC
  • HID_USAGE_GENERIC_KEYBOARD
  • HID_USAGE_GENERIC_KEYPAD
  • HID_USAGE_GENERIC_SYSTEM_CTL
  • HID_USAGE_PAGE_KEYBOARD
  • HID_USAGE_PAGE_CONSUMER
  • HID_USAGE_PAGE_DIGITIZER
  • HID_USAGE_PAGE_SENSOR
  • HID_USAGE_PAGE_BARCODE_SCANNER
  • HID_USAGE_PAGE_WEIGHING_DEVICE
  • HID_USAGE_PAGE_MAGNETIC_STRIPE_READER
  • HID_USAGE_PAGE_TELEPHONY

In-box device drivers only

In addition to blocking support for the previous list of usage pages, the new API also requires that your app runs by using the in-box device drivers that come with Windows 8.1. The API does not support vendor-supplied device drivers.

Peripheral device support only

The HID API is designed primarily for apps that access peripheral devices. The app-developer scenario described earlier applies only to such devices.

Although the API can be used to access internal (non-peripheral) devices, access to these devices is limited to privileged apps that only the device manufacturer creates. App developers cannot access internal devices.

No support for Control Panel apps

Apps created with the HID API are per-user apps. This means that they can't save settings, which is typically a requirement for a Control Panel app.

Point of service (POS) device support

[Get the Barcode scanner and Magnetic stripe reader samples now.]

Windows 8.1 introduces a new Windows.Devices.PointOfService namespace for specialized point-of-service (POS) devices. This release supports barcode scanners and magnetic stripe readers. Use the manufacturer-neutral POS API to write Windows Store apps that can access POS devices from various makers and enable a many-to-many mapping between POS apps and POS devices.

This namespace is based on the industry-standard Unified Point of Service (UPOS) specification. For more info, see the UnifiedPOS website.

For the barcode scanner, device creation occurs by static activation using the GetDefaultAsync method, which gets the first available barcode scanner connected to the tablet (if there is more than one scanner). You can also create a specific device by using the FromIdAsync method, which gets a barcode scanner from a DeviceInformation ID. ClaimScannerAsync gets your app exclusive access to the device and prevents other apps from using it. And EnableAsync gets the device ready for a DataReceived event. The same pattern and API elements apply to the magnetic stripe reader.

These code examples show how to get a barcode scanner that's connected to a tablet, and how to enable it to receive data.

// Creates the barcode scanner, claims it for exclusive use, and enables it to receive data.
var _scanner = null;
var _claimedScanner = null;

function startReceivingData() {
    Windows.Devices.PointOfService.BarcodeScanner.getDefaultAsync().then(function (scanner) {
        if (scanner !== null) {
            _scanner = scanner;

            scanner.claimScannerAsync().done(function (claimedScanner) {
                if (claimedScanner !== null) {
                    _claimedScanner = claimedScanner;
                    claimedScanner.isDecodeDataEnabled = true;

                    claimedScanner.addEventListener("datareceived", onDataReceived);
                    claimedScanner.enableAsync().done(function () {

                        document.getElementById("btnStartReading").disabled = true;
                        document.getElementById("btnEndReading").disabled = false;
                    }, function error(e) {
                        // Failed to enable scanner.
                    });

                } else {
                    // Could not claim the scanner.
                }
            }, function error(e) {
                // Could not claim the scanner.
            });

        } else {
            // Barcode scanner not found. Connect a barcode scanner.
        }

    }, function error(e) {
        // Asynchronous method failed.
    });
}
// Creates the default barcode scanner.

private async Task<bool> CreateDefaultScannerObject()
{
    if (scanner == null)
    {
        
        scanner = await BarcodeScanner.GetDefaultAsync();

        if (scanner != null)
        {
            // UpdateOutput("Default barcode scanner created.");
            // UpdateOutput("Device Id is:" + scanner.DeviceId);
        }
        else
        {
            // UpdateOutput("Barcode scanner not found. Please connect a barcode scanner.");
            return false;
        }
    }
    return true;
}

// Claims the barcode scanner for exclusive use. 

private async Task<bool> ClaimScanner()
{
    if (claimedScanner == null)
    {
        // Claim the barcode scanner.
        claimedScanner = await scanner.ClaimScannerAsync();

        if (claimedScanner != null)
        {
            // UpdateOutput("Barcode scanner claimed successfully.");
           
        }
        else
        {
            // UpdateOutput("Failed to claim the barcode scanner.");
            return false;
        }
    }
    return true;
}

// Enables the barcode scanner to receive data. 

private async Task<bool> EnableScanner()
{
   
    if (claimedScanner == null)
    {
        return false;   
    }
    else
    {   
        await claimedScanner.EnableAsync();
      
        return true;
    }            
  
}
// Creates the barcode scanner.
task<void> Scenario1::CreateDefaultScannerObject()
{
    return create_task(BarcodeScanner::GetDefaultAsync()).then([this] (BarcodeScanner^ _scanner)
    {
        this->scanner = _scanner;
        if (this->scanner != nullptr)
        {            
            // UpdateScannerStatusTextBlock("Barcode scanner created.");
            // UpdateScannerStatusTextBlock("Device ID is:" + this->scanner->DeviceId);
        }
        else
        {
            // UpdateScannerStatusTextBlock("Barcode scanner not found. Connect a barcode scanner.");
            // rootPage->NotifyUser("No barcode scanner found.", NotifyType::StatusMessage);
        }
    });

}

// Claims the barcode scanner for exclusive use.
task<void> Scenario1::ClaimScanner()
{
    return create_task(scanner->ClaimScannerAsync()).then([this] (ClaimedBarcodeScanner^ _claimedScanner)
    {
        this->claimedScanner = _claimedScanner;
        if (claimedScanner != nullptr)
        {
            // UpdateScannerStatusTextBlock("Barcode scanner claimed successfully.");        
        }
        else
        {
            // UpdateScannerStatusTextBlock("Failed to claim barcode scanner.");
        }
    });
}

// Enables the barcode scanner to receive data.
task<void> Scenario1::EnableScanner()
{
    return create_task(claimedScanner->EnableAsync()).then([this](void)
    {
        // UpdateScannerStatusTextBlock("Barcode scanner enabled successfully.");
    });
}   

For more info about these methods, events, and properties, see the Windows.Devices.PointOfService reference.

This API provides an easy migration path for POS developers. You can turn your desktop apps using Microsoft POS for .NET into Windows Store apps using the Windows Runtime and running on tablets. The API model is similar to POS for .NET with some modifications.

USB device support

[Get the Custom USB device access sample now.]

A new Windows 8.1 namespace offers app support for USB devices: Windows.Devices.Usb. You can use it to write a Windows Store app that talks to a custom USB device. "Custom" in this context means a peripheral device for which Microsoft does not provide an in-box class driver.

The official USB specification is the industry standard for hardware manufacturers who make USB peripherals for PCs. Windows includes in-box drivers for most of those devices. For devices that do not have an in-box driver, users can install the generic in-box Winusb.sys driver provided by Microsoft. As they make new peripherals, manufacturers can provide their own custom driver or use Winusb.sys. If they choose Winusb.sys, you can easily write accompanying apps that let users interact with the device. In earlier versions of Windows, such apps were desktop apps, written by using WinUSB Functions. In Windows 8.1, Windows Store apps can be written by using the new Windows.Devices.Usb namespace.

When to use the new USB API

You can use the new API if the following are all true:

  • The device driver is the Microsoft-provided Winusb.sys driver. The namespace does not support manufacturer-supplied device drivers. When you plug in the device, Windows may or may not install Winusb.sys automatically, depending on the design of the device. If the driver is not installed automatically, you must do so manually in Device Manager:

    1. Right-click the device and select Update Driver Software.

    2. In the wizard, select Browse my computer for driver software.

    3. On the next page, select Let me pick from a list of device drivers on my computer.

    4. On the next page, from the list, select Universal Serial Bus devices.

    5. Select WinUsb Device and click Next to install the driver.

  • You provide the info about your device as device capability declarations in the app manifest. This associates your app with the device.

    For more info, see Updating the app manifest package for a USB device.

  • The device belongs to one of the device classes supported by the namespace. Note that a custom device can belong to a predefined USB device class or its functionality can be defined by the manufacturer.

Use the Windows.Devices.Usb namespace for these USB device class, subclass, and protocol codes:

  • CDC control class (class code: 0x02; subclass code: any; protocol code: any)
  • Physical class (class code: 0x05; subclass code: any; protocol code: any)
  • PersonalHealthcare class (class code: 0x0f; subclass code: 0x00; protocol code: 0x00)
  • ActiveSync class (class code: 0xef; subclass code: 0x01; protocol code: 0x01)
  • PalmSync class (class code: 0xef; subclass code: 0x01; protocol code: 0x02)
  • DeviceFirmwareUpdate class (class code: 0xfe; subclass code: 0x01; protocol code: 0x01)
  • IrDA class (class code: 0; subclass code: 0x02; protocol code: 0x00)
  • Measurement class (class code: 0xfe; subclass code: 0x03; protocol code: any)
  • Vendor-specific class (class code: 0xff; subclass code: any; protocol code: any)

When not to use the new USB API

You can't use the new API if either of the following are true:

  • You want your app to access internal devices.Windows.Devices.Usb is for accessing peripheral devices only. A Windows Store app can access internal USB devices only if it is a privileged app that is explicitly declared by the OEM for that system.

  • Your app is a Control Panel app. Apps that use the namespace must be per-user apps. That is, they can communicate with the device but cannot save settings data outside their scope—functionality that's required by many Control Panel apps.

Don't use the Windows.Devices.Usb namespace for these USB device classes:

  • Audio class (0x01)
  • HID class(0x03)
  • Image class (0x06)
  • Printer class (0x07)
  • Mass storage class (0x08)
  • Smart card class (0x0B)
  • Audio/video class (0x10)
  • Wireless controller (such as wireless USB host or hub) (0xE0)

The namespace blocks these USB device classes to prevent conflict with other APIs. For these classes, use other relevant APIs instead. For example, if your device conforms to HID protocol, use Windows.Devices.HumanInterfaceDevice.

Discovering and connecting to a USB device

This example code shows how to search for a USB device and connect to it.

 
    var deviceQueryString = UsbDevice.GetDeviceSelector(deviceVid, devicePid, deviceInterfaceClass);

    var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(deviceQueryString, null);
    
    UsbDevice device = await UsbDevice.FromIdAsync(myDevices[0].Id);

    // Device is in use.
    if (device != null)
    {
        MainPage.Current.NotifyUser("Device " + id + " opened", NotifyType.StatusMessage);
    }
    else
    {
        MainPage.Current.NotifyUser("Unable to open device : " + id, NotifyType.ErrorMessage);
    }

Get started writing a USB-capable Windows Store app by studying the CustomUsbDeviceAccess sample. This sample shows how to communicate with a USB device by using the Windows.Devices.Usb namespace.

Bluetooth device support

[Get the Bluetooth Rfcomm Chat and Bluetooth Generic Attribute Profile samples now.]

For Windows 8.1, Windows Store apps can use the new RFCOMM and GATT (Generic Attribute Profile) Windows Runtime APIs to access Bluetooth devices. These APIs provide access to the Bluetooth BR/EDR and Bluetooth LE transports.

Bluetooth Classic and Bluetooth Smart devices must be first discovered and paired via the Windows 8.1 PC settings UI (PC & devices>Bluetooth) before being accessible via the Windows Runtime APIs for Bluetooth.

You provide info about your device as device-capability declarations in the app manifest. This associates the app with the device.

Here are some key details about the new APIs:

Bluetooth RFCOMMWindows.Devices.Bluetooth.Rfcomm

  • The API lets Windows Store app developers implement Bluetooth profiles built on the RFCOMM protocol—for example, Serial Port Profile (SPP).

  • Client and server roles are provided.

  • Remote Service Discovery Protocol (SDP) records can be accessed and local SDP records can be published.

  • The Sockets.ControlChannelTrigger class is not available for RFCOMM-based sockets.

  • The RFCOMM API prevents access to the following in-box and invalid services:

    Service ID Service (Bluetooth SIG name)

    0x1000

    Service Discovery

    0x1001

    Browse Group Descriptor

    0x1102

    LAN Access Using PPP

    0x1103

    Dialup Networking

    0x1108, 0x1112

    Headset

    0x1109

    Cordless Telephony

    0x110A

    Audio Source

    0x110B

    Audio Sink

    0x110C, 0x110E, 0x110F

    A/V Remote Control

    0x1110

    Intercom

    0x1111

    Fax

    0x1113, 0x1114

    WAP

    0x1115

    PANU

    0x1116

    NAP

    0x1117

    GN

    0x111E, 0x111F

    Handsfree

    0x1124

    Human Interface Device

    0x1126

    HCR Print

    0x1127

    HCR Scan

    0x1128

    Common ISDN Access

    0x112D

    SIM Access

    0x1131

    Headset – HS

    0x1136

    GNSS Server

    0x1200

    PnP Information

    0x1201

    Generic Networking

    0x1203

    Generic Audio

    0x1204

    Generic Telephony

    0x1205, 0x1206

    UPnP

    0x1300, 0x1301, 0x1302

    ESDP UPnP IP

    0x1303

    Video Source

    0x1304

    Video Sink

    0x1305

    Video Distribution

    0x1401

    HDP Source

    0x1402

    HDP Sink

     

Bluetooth GATTWindows.Device.Bluetooth.Gatt

  • The API lets Windows Store app developers implement GATT client profiles for collecting data from low energy (LE) sensors.

  • A Bluetooth 4.0 radio is required to use the GATT API.

  • The GATT API prevents access to the following in-box and invalid services:

    Service ID Service (Bluetooth SIG name)

    0x1812

    HID Over GATT Service

     

  • The GATT API provides read-only access to the following in-box and invalid services:

    Service ID Service (Bluetooth SIG name)

    0x1800

    GAP Service

    0x1801

    GATT Service

    0x1813

    Scan Parameters Service

     

Note  The Windows Runtime APIs for RFCOMM and GATT are not intended for use in Control Panel apps.

Two scenarios give you more info about how to use the Windows.Devices.Bluetooth.Rfcomm API:

Three scenarios give you more info about how to use the Windows.Device.Bluetooth.Gatt API:

3D printer support

[Get the 3D Printing sample now.]

Printing 3D content with Windows 8.1 is similar to printing 2D content. In fact, we've simply extended the IXpsOMPackageWriter and IXpsDocumentPackageTarget interfaces to provide this feature. To send 3D content to a printer from an app in Windows 8.1, your app must access Windows printing and provide formatted 3D content to print.

3D printing in Windows 8.1 involves creating 3D content and passing it through the pipeline of Windows spooler and driver filters to the 3D manufacturing device, such as a 3D printer.

Two interfaces—IXpsDocumentPackageTarget3D and IXpsOMPackageWriter3D—are included in the 3D printing API. IXpsDocumentPackageTarget3D represents a print queue and job details. IXpsOMPackageWriter3D provides methods for sending content into the Windows print pipeline. This interface passes 3D content as opaque streams through spooler and driver filters to the 3D manufacturing device.

The 3D printing interfaces have these characteristics:

  • They support submitting 3D content in Open Packaging Conventions format for printing.

  • They support submitting XPS content for 2D printing, in addition to the 3D content.

  • The 3D content is limited to one 3D model part linking zero or more texture parts and zero or one print ticket parts.

  • The 3D model and texture data are considered an opaque stream by the API, and there is no validation or parsing of any kind.

For a feature overview, go to Supporting 3D printing, and see Quickstart: 3D printing to learn how to add 3D printing to your app.

Scanning support

[Get the Scan sample now.]

You can now scan content from your Windows Store app using a flatbed, feeder, or auto-configured scan source.

The new Windows.Devices.Scanners namespace is built on top of the existing WIA APIs, and is integrated with the Device Access API.

Note  A Scan app is built into Windows 8.1.

For a feature overview, see Scanning (JavaScript and HTML) or Scanning (C#/C++/VB and XAML).