Windows 10, 1607, UWP – Screencast of a WPF App Calling UWP APIs With/Without an .APPX Package

This post is just a companion post to a number of other posts that I’ve written around the desktop app converter, especially;

I’d made a demo of making a simple, blank WPF app and then using it to;

  • Call into UWP APIs
  • Call into UWP APIs that need a package identity
  • Package into a UWP .appx package
  • Show the deployment project template in Visual Studio “15” Preview that helps with debugging

All of that was in the original post referenced above but the video below is a little more up to date. It’s also a little ‘rough and ready’ so excuse the production values Smile

It also lines up with this post where I have a short screen capture of automatically making a .appx package from a .MSI via the Desktop App Converter going end-to-end from the installation of the converter through to installing/uninstalling the app;

A Quick Skip Through the Desktop App Converter

I thought I’d publish this after seeing the great post that @qmatteoq flagged on Twitter today which covers very similar ground with more detail so definitely check out that post as well if you’re interested in this area.

Windows 10, UWP, HoloLens and Switching 2D/3D Views

NB: The usual blog disclaimer for this site applies to posts around HoloLens. I am not on the HoloLens team. I have no details on HoloLens other than what is on the public web and so what I post here is just from my own experience experimenting with pieces that are publicly available and you should always check out the official developer site for the product documentation.

One of the things that I wanted to understand a bit better when I wrote this post;

Baby Steps on my HoloLens Developer Journey

was the interchange between 2D and 3D views on the HoloLens as discussed in this document;

App Model – Switching Views

and I wanted to experiment with seeing if I could get an app up and running which switched between a 2D XAML based view and a 3D Unity based view.

To get going with that, I made a fairly blank Unity project in accordance with the steps here;

Configuring a Unity project for HoloLens

and then I added a cube into my scene so that I had something to look at;

image

and then made sure that I was exporting my project as a XAML based project as I mentioned in this previous post;

Windows 10, UWP, Unity, HoloLens– Small Explorations of D3D and XAML based Unity Projects 

as I had a suspicion that the code that I was going to write might be dependent on having the initial view in the app come from the 2D/XAML world rather than the 3D/D3D world although I have yet to test that suspicion so apply a pinch of salt.

I placed a simple script onto my Cube in the scene above although the script is really a global handler so it didn’t need to be attached onto the cube but I needed something to hang my hat on and so I used the Cube;

image

and that script looks like this;

using UnityEngine;
using System.Collections;
using UnityEngine.VR.WSA.Input;

public class TestScript : MonoBehaviour
{

  GestureRecognizer recognizer;
  // Use this for initialization
  void Start()
  {
    this.recognizer = new GestureRecognizer();
    this.recognizer.TappedEvent += OnTapped;
    this.recognizer.StartCapturingGestures();
  }

  private void OnTapped(InteractionSourceKind source, int tapCount, Ray headRay)
  {
#if !UNITY_EDITOR
    ViewLibrary.ViewManagement.SwitchTo2DViewAsync();
#endif
  }

  // Update is called once per frame
  void Update()
  {

  }
}

and so it’s a very simple script and it’s just waiting for a tap (anywhere) before making a call into this SwitchTo2DViewAsync function and I’ve hidden that from the Unity editor so that it doesn’t have to think about it. The Tap isn’t specific to the Cube in any way hence my earlier comment about the script not really ‘belonging’ to the Cube.

That ViewLibrary code lives in a separate class library that I have tried to bring in to the Unity environment as a plugin;

image

and the way I did that came from this previous blog post;

Windows 10 UWP Unity and Adding a Reference to a (UWP) Class Library

The code inside that ViewManagement class looks like this and it’s a bit experimental at the time of writing but it “seems to work”;

namespace ViewLibrary
{
  using System;
  using System.Threading.Tasks;
  using Windows.ApplicationModel.Core;
  using Windows.UI;
  using Windows.UI.Core;
  using Windows.UI.ViewManagement;
  using Windows.UI.Xaml;
  using Windows.UI.Xaml.Controls;
  using Windows.UI.Xaml.Media;

  public static class ViewManagement
  {
    public static async Task SwitchTo2DViewAsync()
    {
      if (coreView3d == null)
      {
        coreView3d = CoreApplication.MainView;
      }
      if (coreView2d == null)
      {
        coreView2d = CoreApplication.CreateNewView();

        await RunOnDispatcherAsync(
          coreView2d, 
          async () =>
          {
            Window.Current.Content = Create2dUI();
          }
        );
      }
      await RunOnDispatcherAsync(coreView2d, SwitchViewsAsync);
    }
    static UIElement Create2dUI()
    {
      var button = new Button()
      {
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch,
        Content = "Back to 3D",
        Background = new SolidColorBrush(Colors.Red)
      };
      button.Click += async (s, e) =>
      {
        await SwitchTo3DViewAsync();
      };
      return (button);
    }
    static async Task RunOnDispatcherAsync(CoreApplicationView view, 
      Func<Task> action)
    {
      await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
        () => action());
    }
    public static async Task SwitchTo3DViewAsync()
    {
      await RunOnDispatcherAsync(coreView3d, SwitchViewsAsync);
    }
    static async Task SwitchViewsAsync()
    {
      var view = ApplicationView.GetForCurrentView();
      await ApplicationViewSwitcher.SwitchAsync(view.Id);
      Window.Current.Activate();
    }
    static CoreApplicationView coreView3d;
    static CoreApplicationView coreView2d;
  }
}

Mostly, that code came from this blog post about using multiple views in a regular UWP app but I manipulated it around a little here.

If I run this up on the emulator or an a device then I see my initial holographic view of the app containing my Cube;

image

and then if I tap I see;

image

and then if I Click I see;

image

I wouldn’t say that I have a 100% grip on this at the time of finishing this post but I think I understand it better than when I started writing it Smile

I’d like to dig into whether this same approach works with a project that has been exported as D3D rather than as XAML and I’ll update the post as/when I figure that out.

Windows 10, UWP, Unity, HoloLens– Small Explorations of D3D and XAML based Unity Projects

NB: The usual blog disclaimer for this site applies to posts around HoloLens. I am not on the HoloLens team. I have no details on HoloLens other than what is on the public web and so what I post here is just from my own experience experimenting with pieces that are publicly available and you should always check out the official developer site for the product documentation.

In experimenting with Unity for building out holographic apps for HoloLens I’ve got quite used to going into Unity and making a ‘blank’ project as per this recipe;

Configuring a Unity project for HoloLens

in that what I generally do is to make a new, blank 3D project;

image

and then I either make use of the HoloToolkit for Unity or if I’m just doing a quick experiment I’ll change some camera settings;

image

and then I’ll save the scene and change the build settings;

image

and then quite a few times I’ve forgotten to specify that I’m doing holographic development over here;

image

and what I find interesting is that if I make this mistake then the app fails to show up as a ‘holographic’ app on the emulator or on the device.

That is, it turns up in a window;

image

and so my own assumption would be that missing out the important step of selecting the SDK as I should have done (shown below);

image

causes some code path to be taken through the Unity pieces here that does not involve setting up a HolographicSpace and so my app runs as a flat app. That’s my assumption – I did try and test that out in the debugger but couldn’t quite get the right mix of symbols and breakpoints to 100% prove it to me so apply a pinch of salt.

If I switch on the SDK as I was meant to in the first place then I get the view that I would expect for a holographic app.

The first lesson there is then not to forget to reference the right SDK Smile

The other lesson is the difference between choosing a build a D3D project versus building a XAML project from this dialog;

image

If I choose D3D here as above then I get a UWP project which feels pretty streamlined – I end up with a custom class (named App) which implements both IFrameworkView and IFrameworkViewSource and which runs to around 100 lines of code which takes whatever steps Unity needs to get itself bootstrapped into the process.

I don’t find it easy to switch the build type between D3D and XAML once I’ve done the first build of a project so there’s something I need to figure out there but if I set up another project the same way and then do a XAML build then I see a bit more code generated than for the D3D build.

However, I don’t know that most of that generated code actually applies when running on the HoloLens emulator/device.

The code is the usual class App derived from the Windows.UI.Xaml.Application class and it seems to split its Unity initialisation across both OnLaunched and the Activated handler and ultimately creates a Frame and navigates it to a MainPage as the Visual Studio blank UWP app template would do.

That MainPage.xaml then includes some more UI hosting a SwapChainPanel and a splash screen and about 250 lines of code-behind but a lot of that code does not seem to apply to a UWP app running on a holographic device. Most of the code would appear to either be compiled out by conditional compilation or taken out by the logic and the main work appears to be done here;

image

which comes from the MainPage constructor and then seems to bootstrap the same view that I’d see in the D3D exported project.

So…I can use the D3D export if I want to end up with something where there’s no XAML bootstrapped into the process and the XAML export if I want to have ‘XAML’ bootstrapped into the process and it doesn’t feel like there’s a huge amount of difference between the two otherwise which is what I’d hope for.

From a user’s perspective – running the XAML exported project means that you seen a Window for a second or so before the holographic view comes into play and takes over the whole frame so, again, it doesn’t feel dramatically different from running the D3D exported project.