Under the hood, Environment.OSVersion uses the GetVersionEx function, which has been deprecated. The documentation warns about the behavior you observed:
Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2).
The documentation goes on to recommend:
Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, test for the presence of the feature itself.
If the above recommendation is not appropriate for your case, and you really want to check the actual running OS version, then the documentation also provides a hint about this:
To compare the current system version to a required version, use the VerifyVersionInfo function instead of using GetVersionEx to perform the comparison yourself.
The following article has posted a working solution using the VerifyVersionInfo function: Version Helper API for .NET.
Giving full credit to the author of that article, the following code snippet should provide the behavior you are looking for:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(IsWindowsVersionOrGreater(6, 3, 0)); // Plug in appropriate values.
}
[StructLayout(LayoutKind.Sequential)]
struct OsVersionInfoEx
{
public uint OSVersionInfoSize;
public uint MajorVersion;
public uint MinorVersion;
public uint BuildNumber;
public uint PlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string CSDVersion;
public ushort ServicePackMajor;
public ushort ServicePackMinor;
public ushort SuiteMask;
public byte ProductType;
public byte Reserved;
}
[DllImport("kernel32.dll")]
static extern ulong VerSetConditionMask(ulong dwlConditionMask,
uint dwTypeBitMask, byte dwConditionMask);
[DllImport("kernel32.dll")]
static extern bool VerifyVersionInfo(
[In] ref OsVersionInfoEx lpVersionInfo,
uint dwTypeMask, ulong dwlConditionMask);
static bool IsWindowsVersionOrGreater(
uint majorVersion, uint minorVersion, ushort servicePackMajor)
{
OsVersionInfoEx osvi = new OsVersionInfoEx();
osvi.OSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
osvi.MajorVersion = majorVersion;
osvi.MinorVersion = minorVersion;
osvi.ServicePackMajor = servicePackMajor;
// These constants initialized with corresponding definitions in
// winnt.h (part of Windows SDK)
const uint VER_MINORVERSION = 0x0000001;
const uint VER_MAJORVERSION = 0x0000002;
const uint VER_SERVICEPACKMAJOR = 0x0000020;
const byte VER_GREATER_EQUAL = 3;
ulong versionOrGreaterMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
uint versionOrGreaterTypeMask = VER_MAJORVERSION |
VER_MINORVERSION | VER_SERVICEPACKMAJOR;
return VerifyVersionInfo(ref osvi, versionOrGreaterTypeMask,
versionOrGreaterMask);
}
}
Disclaimer: I don't have Windows 10 yet, so I haven't tested the code on Windows 10.