Quickstart: Register an app for an AutoPlay device (XAML)

You can register apps as options for AutoPlay device events. AutoPlay device events are raised when a device is connected to a PC.

Roadmap: How does this topic relate to others? See:

Here we show how to identify your app as an AutoPlay option when a camera is connected to a PC. The app registers as a handler for the WPD\ImageSourceAutoPlay event. This is a common event that the Windows Portable Device (WPD) system raises when cameras and other imaging devices notify it that they are an ImageSource using MTP. For more info, see Windows Portable Devices.

If you are a device manufacturer and you want to associate your Windows Store device app as an AutoPlay handler for your device, you can identify that app in the device metadata. If you associate your app as the auto-installed app for the experience ID of your device, the operating system will discover the association when your device is connected to a PC. If the PC doesn't have your app installed, the operating system will automatically download and install your app. AutoPlay will present your app as the first option for the user to choose as the handler for your device. For more info, see AutoPlay for Windows Store device apps.

Objective: Create an app to handle an AutoPlay device event.

Prerequisites

Microsoft Visual Studio

Instructions

1. Create a new project and add AutoPlay declarations

  1. Open Visual Studio and select New Project from the File menu. In the Visual C# or Visual Basic section, select Windows Store. Name the app AutoPlayDevice_Camera and click OK.

  2. Open the Package.appxmanifest file and select the Capabilities tab. Select the Removable Storage capability. This gives the app access to the data on the camera as a removable storage volume device.

  3. In the manifest file, select the Declarations tab. In the Available Declarations drop-down list, select AutoPlay Device and click Add. Select the new AutoPlay Device item that was added to the Supported Declarations list.

  4. An AutoPlay Device declaration identifies your app as an option when AutoPlay raises a device event for known events.

    In the Launch Actions section, enter the following values for the first launch action.

Setting Value
Verb show
Action Display Name Show Pictures
Content Event WPD\ImageSource
  The **Action Display Name** setting identifies the string that AutoPlay displays for your app. The **Verb** setting identifies a value that is passed to your app for the selected option. You can specify multiple launch actions for an AutoPlay event and use the **Verb** setting to determine which option a user has selected for your app. You can tell which option the user selected by checking the **verb** property of the startup event arguments passed to your app. You can use any value for the **Verb** setting except, **open**, which is reserved. For an example of using multiple verbs in a single app, see [Quickstart: Register an app for AutoPlay content](hh452739\(v=win.10\).md).
  1. In the Available Declarations drop-down list, select File Type Associations and click Add. In the Properties of the new File Type Associations declaration, set the Display Name field to Show Images from Camera and the Name field to camera_association1. In the Supported File Types section, click Add New. Set the File Type field to .jpg. In the Supported File Types section, click Add New again. Set the File Type field of the new file association to .png. For content events, AutoPlay filters out any file types that are not explicitly associated with your app.

  2. Save and close the manifest file.

2. Add XAML UI

  • Open the MainPage.xaml file and add the following XAML to the default <Grid> section.

    <StackPanel Orientation="Vertical" Margin="10,0,-10,0">
        <TextBlock FontSize="24">Device Information</TextBlock>
        <StackPanel Orientation="Horizontal">
            <TextBlock x:Name="DeviceInfoTextBlock" FontSize="18" Height="400" Width="400" VerticalAlignment="Top" />
            <ListView x:Name="ImagesList" HorizontalAlignment="Left" Height="400" VerticalAlignment="Top" Width="400">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <Image Source="{Binding Path=Source}" />
                            <TextBlock Text="{Binding Path=Name}" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapGrid Orientation="Horizontal" ItemHeight="100" ItemWidth="120"></WrapGrid>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
            </ListView>
        </StackPanel>
    </StackPanel>
    

3. Add activation code

The code in this step references the camera as a StorageDevice by passing the device information Id of the camera to the FromId method. The device information Id of the camera is obtained by first casting the event arguments as DeviceActivatedEventArgs, and then getting the value from the DeviceInformationId property.

  • Open the App.xaml.cs or App.xaml.vb file and add the following code to the App class.

    protected override void OnActivated(IActivatedEventArgs args)
    {
        if (args.Kind == ActivationKind.Device)
        {
            Frame rootFrame = null;
            // Ensure that the current page exists and is activated
            if (Window.Current.Content == null)
            {
                rootFrame = new Frame();
                rootFrame.Navigate(typeof(MainPage));
                Window.Current.Content = rootFrame;
            }
            else
            {
                rootFrame = Window.Current.Content as Frame;
            }
            Window.Current.Activate();
    
            // Reference the current page as type MainPage
            var mPage = rootFrame.Content as MainPage;
    
            // Cast the activated event args as DeviceActivatedEventArgs and show images
            var deviceArgs = args as DeviceActivatedEventArgs;
            if (deviceArgs != null)
            {
                mPage.ShowImages(Windows.Devices.Portable.StorageDevice.FromId(deviceArgs.DeviceInformationId));
            }
        }
    
        base.OnActivated(args);
    }
    
    Protected Overrides Sub OnActivated(args As IActivatedEventArgs)
        If args.Kind = ActivationKind.Device Then
            Dim rootFrame As Frame = Nothing
            ' Ensure that the current page exists and is activated
            If Window.Current.Content Is Nothing Then
                rootFrame = New Frame()
                rootFrame.Navigate(GetType(MainPage))
                Window.Current.Content = rootFrame
            Else
                rootFrame = TryCast(Window.Current.Content, Frame)
            End If
            Window.Current.Activate()
    
            ' Reference the current page as type MainPage
            Dim mPage = TryCast(rootFrame.Content, MainPage)
    
            ' Cast the activated event args as DeviceActivatedEventArgs and show images
            Dim deviceArgs = TryCast(args, DeviceActivatedEventArgs)
            If deviceArgs IsNot Nothing Then
                mPage.ShowImages(Windows.Devices.Portable.StorageDevice.FromId(deviceArgs.DeviceInformationId))
            End If
        End If
    
        MyBase.OnActivated(args)
    End Sub
    

4. Add code to display device information

You can obtain information about the camera from the properties of the StorageDevice class. The code in this step displays the device name and other info to the user when the app runs. The code then calls the GetImageList and GetThumbnail methods, which you will add in the next step, to display thumbnails of the images stored on the camera.

  • In the MainPage.xaml.cs or MainPage.xaml.vb file, add the following code to the MainPage class.

    private Windows.Storage.StorageFolder rootFolder;
    
    internal async void ShowImages(Windows.Storage.StorageFolder folder)
    {
        DeviceInfoTextBlock.Text = "Display Name = " + folder.DisplayName + "\n";
        DeviceInfoTextBlock.Text += "Display Type =  " + folder.DisplayType + "\n";
        DeviceInfoTextBlock.Text += "FolderRelativeId = " + folder.FolderRelativeId + "\n";
    
        // Reference first folder of the device as the root
        rootFolder = (await folder.GetFoldersAsync())[0];
        var imageList = await GetImageList(rootFolder);
    
        foreach (Windows.Storage.StorageFile img in imageList)
        {
            ImagesList.Items.Add(await GetThumbnail(img));
        }
    }
    
    Private rootFolder As Windows.Storage.StorageFolder
    
    Friend Async Sub ShowImages(folder As Windows.Storage.StorageFolder)
        DeviceInfoTextBlock.Text = "Display Name = " & folder.DisplayName & vbCr
        DeviceInfoTextBlock.Text &= "Display Type =  " & folder.DisplayType & vbCr
        DeviceInfoTextBlock.Text &= "FolderRelativeId = " & folder.FolderRelativeId & vbCr
    
        ' Reference first folder of the device as the root
        rootFolder = (Await folder.GetFoldersAsync())(0)
        Dim imageList = Await GetImageList(rootFolder)
    
        For Each img In imageList
            ImagesList.Items.Add(Await GetThumbnail(img))
        Next
    End Sub
    

5. Add code to display images

The code in this step displays thumbnails of the images stored on the camera. The code makes asynchronous calls to the camera to get the thumbnail image. However, the next asynchronous call doesn't occur until the previous asynchronous call completes. This ensures that only one request is made to the camera at a time.

  • In the MainPage.xaml.cs or MainPage.xaml.vb file, add the following code to the MainPage class.

    async private System.Threading.Tasks.Task<List<Windows.Storage.StorageFile>> GetImageList(Windows.Storage.StorageFolder folder) 
    {
        var result = await folder.GetFilesAsync();
        var subFolders = await folder.GetFoldersAsync();
        foreach (Windows.Storage.StorageFolder f in subFolders)
            result = result.Union(await GetImageList(f)).ToList();
    
        return (from f in result orderby f.Name select f).ToList();
    }
    
    async private System.Threading.Tasks.Task<Image> GetThumbnail(Windows.Storage.StorageFile img) 
    {
        // Get the thumbnail to display
        var thumbnail = await img.GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.SingleItem,
                                                    100,
                                                    Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale);
    
        // Create a XAML Image object bind to on the display page
        var result = new Image();
        result.Height = thumbnail.OriginalHeight;
        result.Width = thumbnail.OriginalWidth;
        result.Name = img.Name;
        var imageBitmap = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
        imageBitmap.SetSource(thumbnail);
        result.Source = imageBitmap;
    
        return result;
    }
    
    Private Async Function GetImageList(folder As Windows.Storage.StorageFolder) As Task(Of List(Of Windows.Storage.StorageFile))
        Dim result = Await folder.GetFilesAsync()
        Dim subFolders = Await folder.GetFoldersAsync()
        For Each f In subFolders
            result = result.Union(Await GetImageList(f)).ToList()
        Next
    
        Return (From f In result Order By f.Name).ToList()
    End Function
    
    
    Private Async Function GetThumbnail(img As Windows.Storage.StorageFile) As Task(Of Image)
        ' Get the thumbnail to display
        Dim thumbnail = Await img.GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.SingleItem,
                                                    100,
                                                    Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale)
    
        ' Create a XAML Image object bind to on the display page
        Dim result = New Image()
        result.Height = thumbnail.OriginalHeight
        result.Width = thumbnail.OriginalWidth
        result.Name = img.Name
        Dim imageBitmap = New Windows.UI.Xaml.Media.Imaging.BitmapImage()
        imageBitmap.SetSource(thumbnail)
        result.Source = imageBitmap
    
        Return result
    End Function
    

6. Build and run the app

  1. Press F5 to build and deploy the app (in debug mode).
  2. To run your app, connect a camera to your machine. Then select the app from the AutoPlay list of options. Note  Not all cameras advertise for the WPD\ImageSource AutoPlay device event.  

Summary

In this tutorial, you created an app that displays image files from a camera device. You registered the app for the AutoPlay WPD\ImageSource device event.

Auto-launching with AutoPlay

Roadmap for Windows Runtime apps using C# or Visual Basic