While determining the version number of the copy of Windows that a .NET application is running on has been relatively easy with Environment.OSVersion. Knowing exactly which version of Windows it is and what edition it is (Home, Pro, Tablet, Media Center, N, etc) has been a bit more difficult and an ever changing edition set assumes one is actually detectable.
With the introduction of Windows Vista and it's 9 different editions, it seemed as if being able to easily tell the difference between them was going to be even more difficult... not so.
At last Microsoft has provided a simple API for determining which Windows edition (a.k.a. SKU or product type) is being run within a general family as well as provides a way for you to be aware of future versions of Windows without having to change your application down the line.
I present GetProductInfo:
internal static extern bool GetProductInfo(
out ProductType edition);
In order to determine which edition of Windows a PC is running, one need only call
GetProductInfo and capture the output value of the last parameter if the method call is successful:
ProductType edition = ProductType.Undefined;
if (GetProductInfo(6, 0, 0, 0, out edition))
Console.WriteLine("Edition: " + edition);
If we want to be less specific than just a specific version (i.e. Ultimate or not), we can also use a quick switch block to see if the version is of a specific type:
But how does this make your code able to deal with future unannounced or unknown versions? Why are we arbitrarily specifying a version number in our API call?
The enum that
GetProductInfo() uses today is tied to the 126.96.36.199 version of Windows (Vista) and in later versions will likely be updated along with a new version number while still retaining awareness of the old one(s).
This means that when your application built today against Vista is run on a future system that uses a different
ProductType value, the API will recognize that your app is only aware of
ProductTypes that existed in the 188.8.131.52 version of the enum, and return a value of that type instead of returning an unknown value.
Take the switch statement from above... what happens if in the future Microsoft releases Windows Home Edition for Kids and that has a
ProductType value of HomeKids... rather than returning an unknown value, you might receive HomeBasic back instead because you have already specified the version of the enum you are aware of.