Purely something that I noticed while wandering around Visual Studio 2015 Update 1 when it comes to building Universal Windows Apps.
I’m tied up doing other things so can’t really dig into this just yet but I thought I’d make a quick note.
Firstly, in Visual Studio 2015 Update 1 the project templates default to set up your application to target 10586 and to specify a minimum version of 10240.
Here’s the dialog;
That immediately had me thinking about what differences there might be between 10240 and 10586 and I’m pretty sure that there’s a need for a really great diff tool here because I have a suspicion that this is going to get quite complicated over time.
If I dig into c:\program files (x86)\Windows Kits\10\Platforms\UAP then I see that for 10240 the definition of the Universal Windows Platform (i.e. a set of contracts which are themselves sets of APIs) looked like this;
<?xml version='1.0' encoding='utf-8'?> <ApplicationPlatform name='UAP' friendlyName='Windows 10' version='10.0.10240.0'> <MinimumVisualStudioVersion>14.0.22213.01</MinimumVisualStudioVersion> <ContainedApiContracts> <ApiContract name='Windows.Foundation.FoundationContract' version='126.96.36.199' /> <ApiContract name='Windows.Foundation.UniversalApiContract' version='188.8.131.52' /> <ApiContract name='Windows.Networking.Connectivity.WwanContract' version='184.108.40.206' /> </ContainedApiContracts> </ApplicationPlatform>
whereas in 10586 it has grown;
<?xml version='1.0' encoding='utf-8'?> <ApplicationPlatform name='UAP' friendlyName='Windows 10' version='10.0.10586.0'> <MinimumVisualStudioVersion>14.0.22213.01</MinimumVisualStudioVersion> <ContainedApiContracts> <ApiContract name='Windows.ApplicationModel.Calls.CallsVoipContract' version='220.127.116.11' /> <ApiContract name='Windows.Devices.Printers.PrintersContract' version='18.104.22.168' /> <ApiContract name='Windows.Foundation.FoundationContract' version='22.214.171.124' /> <ApiContract name='Windows.Foundation.UniversalApiContract' version='126.96.36.199' /> <ApiContract name='Windows.Graphics.Printing3D.Printing3DContract' version='188.8.131.52' /> <ApiContract name='Windows.Networking.Connectivity.WwanContract' version='184.108.40.206' /> </ContainedApiContracts> </ApplicationPlatform>
and so it looks like printing and 3d printing and VOIP calling have become universal – the UniversalApiContract has also moved to V2 as has the 3D printing contract.
Now’s the point where I’d like a nice diff tool to show me what has happened in these contracts from V220.127.116.11 to V18.104.22.168 and I don’t know the best way of finding that right now – within the UnionMetadata folder there is the nice Windows.winmd file which can be disassembled but I’m not aware of a tool which will do a comparison based on API Contracts and show me deltas. It strikes me that such a tool might need to be written if it doesn’t exist and maybe I need to write it but that’d have to be another day.
Update – 4th January, 2016 – Chris dropped me a line to flag the tool that he’d written here for exactly that purpose – I’m going to give that a try and see if it helps with diff’ing WinRT platform versions.
Looking at the extension SDKs…
It looks like various contracts in the desktop platform have moved to V2.0 – e.g.
and the Windows.Devices.Printers.PrintersContract has moved from desktop into Universal. There are probably a bunch of other changes here too, I just had a quick look.
In the IoT platform, it looks like the 2 contracts within have both moved to V22.214.171.124;
<?xml version='1.0' encoding='utf-8'?> <FileList TargetPlatform='UAP' TargetPlatformMinVersion='10.0.0.1' TargetPlatformVersion='10.0.10586.0' SDKType='Platform' DisplayName='Windows IoT Extensions for the UWP' AppliesTo='WindowsAppContainer' MinVSVersion='14.0' ProductFamilyName='Windows.IoT' SupportsMultipleVersion='Error' TargetFramework='.NETCore, version=v4.5.3;' SupportPrefer32Bit='True' MoreInfo='http://www.microsoft.com/en-us/server-cloud/internet-of-things.aspx'> <ContainedApiContracts> <ApiContract name='Windows.Devices.DevicesLowLevelContract' version='126.96.36.199'/> <ApiContract name='Windows.System.SystemManagementContract' version='188.8.131.52'/> </ContainedApiContracts> </FileList>
In the mobile platform, various contracts have moved to V184.108.40.206 such as;
and the Windows.ApplicationModel.Calls.CallsVoipContract has moved from mobile into Universal.
In the team platform, nothing seems to have changed as far as I can see.
What does this all mean? I’m not sure that I have it properly thought through at the time of writing but I find myself thinking about;
- Existing code that checks whether printing contract V220.127.116.11 is available and then uses it. In a 10586 world I’m guessing that this code will now find that contract on more device families than it did on 10240 if V18.104.22.168 of that contract has become universal?
- New code that targets 10586 but specifies a minimum of 10240. That code could;
- use APIs from the Windows.Graphics.Printing3D.PrintingContract but that contract wasn’t part of the UAP in 10240 so unless the code explicitly checked that it was on V2.0 of the UAP it would fail.
- use APIs from the Windows.Foundation.UniversalApiContract V22.214.171.124 that weren’t present in the V126.96.36.199 contract and so, again, unless the code explicitly checked that it was on V2.0 of the UAP it would fail.
I could be wrong in that, it’s just some sketchy initial thoughts but it feels to me that the arrival of 10586 makes the versioning aspect of the UWP platforms (today – UAP/Desktop/IoT/Mobile/Team) come to life.
- an application which specifies 10586 as both the minimum and the target version only needs to think about whether API contracts are present as the app crosses device families.
- an application which specifies 10586 as the target version and 10240 as the minimum version has to think about whether API contracts are present and at the right version as it crosses device families.
I think most people will be way ahead of me in terms of having already thought all of this through but the reality of 10586 on my system made me think about it a little more than I had to date.
(Feel free to send me corrections, this is just sketchy thinking right now).
Addition – An Example
If I make a blank UWP project in Visual Studio 2015 Update 1 and leave my target version at 10586 and my minimum at 10240 then I can write this line of code;
var x = Windows.Devices.Printers.Print3DDevice.GetDeviceSelector();
and it compiles, builds, runs just fine.
However, if I change my settings such that the target is set to 10240 then, naturally, it won’t build;
What I think would be really useful here would be for Visual Studio to be monitoring my MINIMUM and TARGET settings and looking at the APIs I’m using, interrogating their metadata and popping up some kind of tooltip to tell me;
“Hey, you just used an API that isn’t present in the MINIMUM version that you’ve specified for the project, you need to take care”
or something along those lines. Maybe that’s a job for a plug-in but I’d like to see it.
Addition 2 – A Helpful Tool
I was chatting around this with Andy via mail and he highlighted the PlatformSpecific.Analyzer tool that Lucian Wischik has written and put into NuGet and out on github;
The document page for this is here;
and I think this is already well on the way to what I’d like to see Visual Studio do for me by default.
If I go back to the line of code that I wrote above with Lucian’s analyzer plugged in then I can configure it such that warnings/errors both while coding and at compile time – e.g. here’s one that is platform specific;
and here’s one that is version specific;
and that seems like a massive help and here’s what I really like – if I now change both my target version and my minimum verrsion to 10586 then the version specific code error goes away;
which is what I’d hope for and, yes, it comes back again if I change my minimum version back to 10240.
I’ll be installing this one by default from here on in