Jerry Nixon @Work: Understanding TargetDeviceFamily

Jerry Nixon on Windows

Monday, July 11, 2016

Understanding TargetDeviceFamily

imageIf you are like me, you might spelunk from time to time in the bowels of your application's manifest file. But, "why?", you might ask, "Isn't everything in the manifest revealed in the graphical editor in Visual Studio?" Oh, you poor child. Allow me to enlighten you on this one: No.

One such setting is the <TargetDeviceFamily /> node, the child of <Dependencies />, the child of <Package />.

You can find it documented on MSDN where it provides this illuminating prose: "Identifies the device family that your package targets." There are some examples, sure, but I wanted to take a moment and make it painstakingly clear. I want to remove any doubt and leave you with the confidence to look at your manifest and edit it without fear.

Fact is, you set this when you create your project. The dialog above appears when you create a new Universal Windows Platform app. It's asking you the Target and Minimum version. But, of what? It is setting the initial versions of the "Windows.Universal" target device family.

image

If you want to change the versions you have selected, you don't edit the manifest file, you edit your project file. Just right-click your project and select properties (or double-click the properties node in Solution Explorer). On the Application tab, you will find the following UI.

image

As interesting as this is, it's all about the version. Picking that can be a real test of your understanding of UWP by itself. But, what about Windows.Universal?

Scenario 1: Universal only

image

This is perfectly valid.

The Universal Windows platform is an API surface common to all Windows apps across Device Families. Specifying, "Windows.Universal" is basically saying to the system that you want to use what's already there. But. this also means your Windows app can run on any device family. You are not limiting your app. Today's options include: Team (Surface hub), Desktop, Mobile (including Phone), Xbox, Holographic, IoT, and anything else we dream up down the road.

Scenario 2: Universal plus

image

This is not valid.

Why? Well, it's not valid because "Mobile" is already included in "Universal". It's like using a wildcard with a specific filter. You still get everything. If you include "Universal" There's no reason to include any other device family. This should make you ask: "What id I only included Mobile?"

Scenario 3: Just one

image

Now, this is valid.

In this scenario, I am indicating my Windows app still uses the Universal Windows Platform, but only on Mobile. Does it mean the API surface is different? No, the universal API surface is identical. What it means is that your Windows app is intended for Mobile, and only for Mobile.

You might ask, "Can I install an app like this on Desktop?" And the answer is "No". The application is declaring its intention. In fact, hold on to the word "intention" because that's what the TargetDeviceFamily node is really all about. Not about capabilities.

Scenario 4: More than one

image

This is also valid.

In this scenario, I am indicating my Windows app is just like Scenario 3. That is, my app is intended for Windows.Mobile. But, I am also indicating my Windows app is intended for Xbox. If you try to install it on Desktop, then it will fail. That's because my Windows app has explicitly declared its intentions for only the Mobile and Xbox device families.

Now, you might ask, does including all the device families in your TargetDeviceFamily node basically equate to using "Windows.Universal"? That's a good question. Something like this:

Scenario 5: All of them

image

This is also valid. (though the version numbers aren't)

You're right. Including all the possible device families is the same as using "Windows.Universal" except for this: this list is explicit and not implicit - should a device family ever be added, this will never include it. It's simply easier to use "Windows.Universal" if your app doesn't have a specific target.

Aside: The upside of this approach is you can have unique versions for every family, if that is what is right for your Windows app.

Question 1

Can I use "Windows.Universal" but still limit my app to Desktop?

The answer is yes.

In the Microsoft DevCenter - what developers usually mean when they say the "Windows Store" - you can specify the target device family. Like this:

image

Aside: this is also enforced during installation. An app marked as Desktop-only cannot be side-loaded on a Mobile device. But an app marked Universal can be side-loaded on Mobile, even if you mark it as Desktop-only in the Dev Center.

Question 2

Does the Store override my manifest?

The answer is no.

This does not override your manifest, by the way. Your manifest is saying, "I am writing this app for these device families" while the settings above are saying, "On what platforms should the Windows Store make my app available?" I hope you see the difference. The screenshot in Question 1 shows what it looks like with Windows.Universal, but an explicit manifest would reduce the options in the DevCenter to the options indicated in TargetDeviceFamily.

Aside: What if you change your app from Universal to Mobile-only. Do previously installed versions on Desktop devices get uninstalled? The answer is no. We never uninstall an app from your device without your invoking it.

Question 3

I noticed each family has its own version. If one device family changes and breaks my app, is it the right thing to do to list that family explicitly with a tweaked min/target version number?

The answer is yes.

In a way, this is the real reason for the syntax in the first place. Perhaps one device family accelerates its capabilities faster than others, perhaps there is a bug in a certain version, or perhaps a device family is deprecated. The granularity of this syntax give you the control to specify what you need to make your Windows app work best.

Aside: this doesn't mean the project properties graphical editor shows more than one device family. In fact, it shows Windows.Universal even when you only have a specific family like Mobile or Xbox. Let's call it a "feature" of the editor, and leave it at that. Change the versions like that and it's a magnificent crash.

Conclusion

That's it. The Universal Windows Platform is a single, reliable, consistent API surface across device families. Accessing a file on IoT is the same on HoloLens, is the same on Xbox, is the same on Desktop. UWP makes universal Windows apps possible, makes development simpler, and delivers a future-ready architecture. The TargetDeviceFamily node in your app's manifest is not about capabilities, it's about the developer's intention for the app - where do you want it to run, not what capabilities do you get.