ここでは、現在のOSのバージョン情報やOSの種類等を取得する方法について説明します。
OSのバージョン情報は、EnvironmentクラスのOSVersionプロパティを使って取得できます。OSVersionプロパティで取得できるOperatingSystemオブジェクトのVersionプロパティで、OSのバージョンが分かります。また、ServicePackプロパティで、OSのサービスパックの情報が分かります。さらに、Platformプロパティで、OSがWindows 95系かNT系かが分かります。
注意:Windows 8.1以上、もしくはWindows Server 2012 R2以上では、Environment.OSVersionプロパティが正しいバージョン「6.3」を返さずに、「6.2」と返す可能性があります。これについて詳しくは、後述します。
以下の例では、OSVersionプロパティを使って、現在のOSの情報を表示しています。
'OSの情報を取得する Dim os As System.OperatingSystem = System.Environment.OSVersion 'OSの情報を表示する Console.WriteLine(os.ToString()) 'Windows 8.1では、「Microsoft Windows NT 6.2.9200.0」 '次のようにしても同じ(.NET Framework 2.0以降) Console.WriteLine(os.VersionString) 'OSのバージョンを表示する Console.WriteLine(os.Version.ToString()) 'Windows 8では、「6.2.9200.0」 'OSの各バージョン情報を表示する 'OSのPlatformIDを表示する Console.WriteLine(os.Platform) 'Windows 8では、「Win32NT」 'OSのメジャーバージョン番号を表示する Console.WriteLine(os.Version.Major) 'Windows 8では、「6」 'OSのマイナーバージョン番号を表示する Console.WriteLine(os.Version.Minor) 'Windows 8では、「2」 'OSのビルド番号を表示する Console.WriteLine(os.Version.Build) 'Windows 8では、「9200」 'OSのリビジョン番号を表示する Console.WriteLine(os.Version.Revision) 'Windows 8では、「0」 'OSのサービスパックのバージョンを表示する(.NET Framework 2.0以降) Console.WriteLine(os.ServicePack) 'Windows 8では、空の文字列 'OSのメジャーリビジョン番号を表示する(.NET Framework 2.0以降) Console.WriteLine(os.Version.MajorRevision) 'Windows 8では、「0」 'OSのマイナーリビジョン番号を表示する(.NET Framework 2.0以降) Console.WriteLine(os.Version.MinorRevision) 'Windows 8では、「0」
//OSの情報を取得する System.OperatingSystem os = System.Environment.OSVersion; //OSの情報を表示する Console.WriteLine(os.ToString()); //Windows 8.1では、「Microsoft Windows NT 6.2.9200.0」 //次のようにしても同じ(.NET Framework 2.0以降) Console.WriteLine(os.VersionString); //OSのバージョンを表示する Console.WriteLine(os.Version.ToString()); //Windows 8では、「6.2.9200.0」 //OSの各バージョン情報を表示する //OSのPlatformIDを表示する Console.WriteLine(os.Platform); //Windows 8では、「Win32NT」 //OSのメジャーバージョン番号を表示する Console.WriteLine(os.Version.Major); //Windows 8では、「6」 //OSのマイナーバージョン番号を表示する Console.WriteLine(os.Version.Minor); //Windows 8では、「2」 //OSのビルド番号を表示する Console.WriteLine(os.Version.Build); //Windows 8では、「9200」 //OSのリビジョン番号を表示する Console.WriteLine(os.Version.Revision); //Windows 8では、「0」 //OSのサービスパックのバージョンを表示する(.NET Framework 2.0以降) Console.WriteLine(os.ServicePack); //Windows 8では、空の文字列 //OSのメジャーリビジョン番号を表示する(.NET Framework 2.0以降) Console.WriteLine(os.Version.MajorRevision); //Windows 8では、「0」 //OSのマイナーリビジョン番号を表示する(.NET Framework 2.0以降) Console.WriteLine(os.Version.MinorRevision); //Windows 8では、「0」
次に、現在のOSが指定したバージョンより上かどうかを調べる例を紹介します。以下の例では、OSがWindows Vista以降か、さらにWindows 7以降かを調べています。
'OSのバージョン情報を取得する Dim os As System.OperatingSystem = System.Environment.OSVersion 'Windows NT系か調べる If os.Platform = PlatformID.Win32NT Then 'メジャーバージョン番号が6以上ならば、Vista(または、Server 2008)以降 If os.Version.Major >= 6 Then Console.WriteLine("OSは、Windows Vista以降です。") 'マイナーバージョン番号が1以上ならば、7(または、Server 2008 R2)以降 If os.Version.Minor >= 1 Then Console.WriteLine("OSは、Windows 7以降です。") End If End If End If
//OSのバージョン情報を取得する System.OperatingSystem os = System.Environment.OSVersion; //Windows NT系か調べる if (os.Platform == PlatformID.Win32NT) { //メジャーバージョン番号が6以上ならば、Vista(または、Server 2008)以降 if (os.Version.Major >= 6) { Console.WriteLine("OSは、Windows Vista以降です。"); //マイナーバージョン番号が1以上ならば、7(または、Server 2008 R2)以降 if (os.Version.Minor >= 1) { Console.WriteLine("OSは、Windows 7以降です。"); } } }
補足:Windows XP互換モードでは、Environment.OSVersionと、後述するGetVersionExが別の値を返すことがあるという不具合が「互換モードでのSystem.Environment.クラスとWin32 APIの動作違い | Microsoft Connect」で報告されています。
Windowsのバージョンと製品名を表にまとめます。バージョンは、「(メジャーバージョン番号).(マイナーバージョン番号)」です。
この表には、.NET Framework非対応のOSも含まれています。
この表は、MSDNの「OSVERSIONINFOEX structure」やWikipediaの「Comparison of Microsoft Windows versions」を参考にして作成しました。
OSの製品名 | バージョン |
---|---|
Windows 10 | 10.0 |
Windows Server 2016 | 10.0 |
Windows 8.1 | 6.3 |
Windows Server 2012 R2 | 6.3 |
Windows 8 | 6.2 |
Windows Server 2012 | 6.2 |
Windows 7 | 6.1 |
Windows Server 2008 R2 | 6.1 |
Windows Home Server 2011 | 6.1 |
Windows Vista | 6.0 |
Windows Server 2008 | 6.0 |
Windows XP Professional x64 Edition | 5.2 |
Windows Server 2003 | 5.2 |
Windows Server 2003 R2 | 5.2 |
Windows Home Server | 5.2 |
Windows XP | 5.1 |
Windows 2000 | 5.0 |
Windows Millennium Edition | 4.90 |
Windows 98 Second Edition | 4.10 |
Windows 98 | 4.10 |
Windows NT 4.0 | 4.0 |
Windows 95 | 4.0 |
Windows NT 3.51 | 3.51 |
Windows NT 3.5 | 3.5 |
Windows NT 3.1 | 3.1 |
OperatingSystem.Platformプロパティは、PlatformID列挙値として取得できます。PlatformID列挙値の意味は、以下の通りです。
PlatformID列挙体のメンバ名 | 説明 | 基になる値 |
---|---|---|
Win32NT | Windows NT系のOSです。(Windows XP, Vista, 7, 8, Server 2003, Server 2008, Server 2012など) | 2 |
Win32Windows | Windows 95系のOSです。(Windows 95, 98, Meなど) | 1 |
Win32S | Win32sです。 | 0 |
WinCE | Windows CEです。 | 3 |
Unix | Unixです。(.NET Framework 2.0以降) | 4 |
Xbox | Xbox 360です(開発プラットフォーム)。(.NET Framework 3.5以降) | 5 |
MacOSX | Macintoshです。(.NET Framework 3.5以降) | 6 |
WMIのWin32_OperatingSystemクラスを使用してもOSのバージョンを取得することができます。Environment.OSVersionプロパティでは取得できないような情報も得ることができます。
なおWin32_OperatingSystemクラスを使った例は、「メモリの合計サイズ、利用可能なメモリのサイズなどを取得する」でも紹介しています。
下に例を示します。この例を実行するには、System.Management.dllを参照設定に追加する必要があります。
Dim mc As New System.Management.ManagementClass("Win32_OperatingSystem") Dim moc As System.Management.ManagementObjectCollection = mc.GetInstances() For Each mo As System.Management.ManagementObject In moc '簡単な説明(Windows 8.1では「Microsoft Windows 8.1 Pro」等) Console.WriteLine(mo("Caption")) 'バージョン(Windows 8.1では、「6.3.9600」) Console.WriteLine(mo("Version")) 'ビルド番号(Windows 8.1では「9600」) Console.WriteLine(mo("BuildNumber")) 'OSのタイプ(Windows NT系は「18」) Console.WriteLine(mo("OSType")) '0:ワークステーション 1:ドメインコントローラ 2:サーバー Console.WriteLine(mo("ProductType")) 'サービスパック(Windows 8.1ではNULL) Console.WriteLine(mo("CSDVersion")) '言語(日本語は「1041」) Console.WriteLine(mo("OSLanguage")) '製品スイートを示すビットフラグ(Enterprise、BackOffice、Terminalなど) Console.WriteLine(mo("OSLanguage")) Next moc.Dispose() mc.Dispose()
System.Management.ManagementClass mc = new System.Management.ManagementClass("Win32_OperatingSystem"); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { //簡単な説明(Windows 8.1では「Microsoft Windows 8.1 Pro」等) Console.WriteLine(mo["Caption"]); //バージョン(Windows 8.1では、「6.3.9600」) Console.WriteLine(mo["Version"]); //ビルド番号(Windows 8.1では「9600」) Console.WriteLine(mo["BuildNumber"]); //OSのタイプ(Windows NT系は「18」) Console.WriteLine(mo["OSType"]); //0:ワークステーション 1:ドメインコントローラ 2:サーバー Console.WriteLine(mo["ProductType"]); //サービスパック(Windows 8.1ではNULL) Console.WriteLine(mo["CSDVersion"]); //言語(日本語は「1041」) Console.WriteLine(mo["OSLanguage"]); //製品スイートを示すビットフラグ(Enterprise、BackOffice、Terminalなど) Console.WriteLine(mo["OSLanguage"]); } moc.Dispose(); mc.Dispose();
Win32 APIのGetVersionEx functionを使うことによって、OSのバージョン情報を取得することもできます。
ただしWindows 8.1からは、GetVersionExはdeprecated(廃止予定)とされ、正しいバージョンを返さない可能性があります。詳しくは、後述します。
以下にGetVersionExを使用した例を示します。
<System.Runtime.InteropServices.StructLayout( _ System.Runtime.InteropServices.LayoutKind.Sequential)> _ Public Structure OSVERSIONINFO Public dwOSVersionInfoSize As Integer Public dwMajorVersion As Integer Public dwMinorVersion As Integer Public dwBuildNumber As Integer Public dwPlatformId As Integer <System.Runtime.InteropServices.MarshalAs( _ System.Runtime.InteropServices.UnmanagedType.ByValTStr, _ SizeConst:=128)> _ Public szCSDVersion As String End Structure 'Windows 2000以降は、OSVERSIONINFOEXも使える <System.Runtime.InteropServices.StructLayout( _ System.Runtime.InteropServices.LayoutKind.Sequential)> _ Public Structure OSVERSIONINFOEX Public dwOSVersionInfoSize As UInteger Public dwMajorVersion As UInteger Public dwMinorVersion As UInteger Public dwBuildNumber As UInteger Public dwPlatformId As UInteger <System.Runtime.InteropServices.MarshalAs( _ System.Runtime.InteropServices.UnmanagedType.ByValTStr, _ SizeConst:=128)> _ Public szCSDVersion As String Public wServicePackMajor As Short Public wServicePackMinor As Short Public wSuiteMask As Short Public wProductType As Byte Public wReserved As Byte End Structure <System.Runtime.InteropServices.DllImport("kernel32")> _ Public Shared Function GetVersionEx(ByRef osvi As OSVERSIONINFOEX) As Boolean End Function 'Button1のClickイベントハンドラ Private Sub Button1_Click(sender As Object, e As EventArgs) _ Handles Button1.Click Dim osvi As New OSVERSIONINFOEX() osvi.dwOSVersionInfoSize = _ CUInt(System.Runtime.InteropServices.Marshal.SizeOf(osvi)) GetVersionEx(osvi) 'メジャーバージョン番号 Console.WriteLine(osvi.dwMajorVersion) 'マイナーバージョン番号 Console.WriteLine(osvi.dwMinorVersion) 'ビルド番号 Console.WriteLine(osvi.dwBuildNumber) 'PlatformId Console.WriteLine(osvi.dwPlatformId) 'サービスパック Console.WriteLine(osvi.szCSDVersion) '0:ワークステーション 1:ドメインコントローラ 2:サーバー Console.WriteLine(osvi.wProductType) '製品スイートを示すビットフラグ(Enterprise、BackOffice、Terminalなど) Console.WriteLine(osvi.wSuiteMask) End Sub
[System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Sequential)] public struct OSVERSIONINFO { public int dwOSVersionInfoSize; public int dwMajorVersion; public int dwMinorVersion; public int dwBuildNumber; public int dwPlatformId; [System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; } //Windows 2000以降は、OSVERSIONINFOEXも使える [System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Sequential)] public struct OSVERSIONINFOEX { public uint dwOSVersionInfoSize; public uint dwMajorVersion; public uint dwMinorVersion; public uint dwBuildNumber; public uint dwPlatformId; [System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public short wServicePackMajor; public short wServicePackMinor; public short wSuiteMask; public byte wProductType; public byte wReserved; } [System.Runtime.InteropServices.DllImport("kernel32")] public static extern bool GetVersionEx(ref OSVERSIONINFOEX osvi); //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { OSVERSIONINFOEX osvi = new OSVERSIONINFOEX(); osvi.dwOSVersionInfoSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(osvi); GetVersionEx(ref osvi); //メジャーバージョン番号 Console.WriteLine(osvi.dwMajorVersion); //マイナーバージョン番号 Console.WriteLine(osvi.dwMinorVersion); //ビルド番号 Console.WriteLine(osvi.dwBuildNumber); //PlatformId Console.WriteLine(osvi.dwPlatformId); //サービスパック Console.WriteLine(osvi.szCSDVersion); //0:ワークステーション 1:ドメインコントローラ 2:サーバー Console.WriteLine(osvi.wProductType); //製品スイートを示すビットフラグ(Enterprise、BackOffice、Terminalなど) Console.WriteLine(osvi.wSuiteMask); }
Windows 2000 APIのVerifyVersionInfo functionとVerSetConditionMask functionを使用すれば、現在のOSが指定したバージョンより上か(あるいは、下か、等しいか)を知ることができます。ただしVerifyVersionInfoができるのは比較することだけで、ズバリとバージョン番号を取得することはできません。
補足:一つ一つのバージョンをしらみつぶしに調べていけば、VerifyVersionInfoでもOSのバージョンを特定することはできます。その例が、「Windows8.1でもバージョン情報を正しく取得する C#編」などで紹介されています。
以下に、VerifyVersionInfoを使用した例を示します。このIsWindowsVersionOrGreaterメソッドを使えば、現在のOSが指定されたバージョン以上かを調べることができます。例えば、現在のOSがWindows 8.1以上かを調べるには「IsWindowsVersionOrGreater(6, 3, 0)」を呼び出して、Trueが返されたらWindows 8.1以上です。
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _ Private Shared Function VerifyVersionInfo( _ <System.Runtime.InteropServices.In> _ ByRef lpVersionInfo As OSVERSIONINFOEX, _ dwTypeMask As UInteger, _ dwlConditionMask As ULong) As Boolean End Function <System.Runtime.InteropServices.DllImport("kernel32.dll")> _ Private Shared Function VerSetConditionMask( _ dwlConditionMask As ULong, _ dwTypeBitMask As UInteger, _ dwConditionMask As Byte) As ULong End Function Private Const VER_MINORVERSION As UInteger = &H1 'dwMajorVersion Private Const VER_MAJORVERSION As UInteger = &H2 'dwMinorVersion Private Const VER_BUILDNUMBER As UInteger = &H4 'dwBuildNumber Private Const VER_PLATFORMID As UInteger = &H8 'dwPlatformId Private Const VER_SERVICEPACKMINOR As UInteger = &H10 'wServicePackMajor Private Const VER_SERVICEPACKMAJOR As UInteger = &H20 'wServicePackMinor Private Const VER_SUITENAME As UInteger = &H40 'wSuiteMask Private Const VER_PRODUCT_TYPE As UInteger = &H80 'wProductType '現在の値と指定された値が同じでなければならない Private Const VER_EQUAL As Byte = 1 '現在の値が指定された値より大きくなければならない Private Const VER_GREATER As Byte = 2 '現在の値が指定された値より大きいか同じでなければならない Private Const VER_GREATER_EQUAL As Byte = 3 '現在の値が指定された値より小さいくなければならない Private Const VER_LESS As Byte = 4 '現在の値が指定された値より小さいか同じでなければならない Private Const VER_LESS_EQUAL As Byte = 5 '指定されたwSuiteMaskがすべて含まれていななければならない Private Const VER_AND As Byte = 6 '指定されたwSuiteMaskの少なくとも1つが含まれていななければならない Private Const VER_OR As Byte = 7 <System.Runtime.InteropServices.StructLayout( _ System.Runtime.InteropServices.LayoutKind.Sequential)> _ Public Structure OSVERSIONINFOEX Public dwOSVersionInfoSize As UInteger Public dwMajorVersion As UInteger Public dwMinorVersion As UInteger Public dwBuildNumber As UInteger Public dwPlatformId As UInteger <System.Runtime.InteropServices.MarshalAs( _ System.Runtime.InteropServices.UnmanagedType.ByValTStr, _ SizeConst:=128)> _ Public szCSDVersion As String Public wServicePackMajor As Short Public wServicePackMinor As Short Public wSuiteMask As Short Public wProductType As Byte Public wReserved As Byte End Structure ''' <summary> ''' 現在のOSが指定されたバージョン以上かを調べる ''' </summary> ''' <param name="majorVersion"> ''' メジャーバージョン番号。負の数の時は調べない。</param> ''' <param name="minorVersion"> ''' マイナーバージョン番号。負の数の時は調べない。</param> ''' <param name="servicePackMajor"> ''' サービスパックのメジャーバージョン番号。負の数の時は調べない。</param> ''' <returns>現在のOSが指定されたバージョン以上ならTrue。</returns> Public Shared Function IsWindowsVersionOrGreater( _ majorVersion As Integer, _ minorVersion As Integer, _ servicePackMajor As Integer) As Boolean If majorVersion < 0 AndAlso _ minorVersion < 0 AndAlso _ servicePackMajor < 0 Then Return True End If 'lpVersionInfo、dwTypeMask、dwlConditionMaskを作成する Dim osvi As New OSVERSIONINFOEX() Dim typeMask As UInteger = 0 Dim conditionMask As ULong = 0 If 0 < majorVersion Then osvi.dwMajorVersion = CUInt(majorVersion) conditionMask = VerSetConditionMask(conditionMask, _ VER_MAJORVERSION, VER_GREATER_EQUAL) typeMask = typeMask Or VER_MAJORVERSION End If If 0 < minorVersion Then osvi.dwMinorVersion = CUInt(minorVersion) conditionMask = VerSetConditionMask(conditionMask, _ VER_MINORVERSION, VER_GREATER_EQUAL) typeMask = typeMask Or VER_MINORVERSION End If If 0 < servicePackMajor Then osvi.wServicePackMajor = CShort(servicePackMajor) conditionMask = VerSetConditionMask(conditionMask, _ VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL) typeMask = typeMask Or VER_SERVICEPACKMAJOR End If 'VerifyVersionInfoを呼び出す Return VerifyVersionInfo(osvi, typeMask, conditionMask) End Function
[System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool VerifyVersionInfo( [System.Runtime.InteropServices.In] ref OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern ulong VerSetConditionMask( ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask); private const uint VER_MINORVERSION = 0x0000001; //dwMajorVersion private const uint VER_MAJORVERSION = 0x0000002; //dwMinorVersion private const uint VER_BUILDNUMBER = 0x0000004; //dwBuildNumber private const uint VER_PLATFORMID = 0x0000008; //dwPlatformId private const uint VER_SERVICEPACKMINOR = 0x0000010; //wServicePackMajor private const uint VER_SERVICEPACKMAJOR = 0x0000020; //wServicePackMinor private const uint VER_SUITENAME = 0x0000040; //wSuiteMask private const uint VER_PRODUCT_TYPE = 0x0000080; //wProductType //現在の値と指定された値が同じでなければならない private const byte VER_EQUAL = 1; //現在の値が指定された値より大きくなければならない private const byte VER_GREATER = 2; //現在の値が指定された値より大きいか同じでなければならない private const byte VER_GREATER_EQUAL = 3; //現在の値が指定された値より小さいくなければならない private const byte VER_LESS = 4; //現在の値が指定された値より小さいか同じでなければならない private const byte VER_LESS_EQUAL = 5; //指定されたwSuiteMaskがすべて含まれていななければならない private const byte VER_AND = 6; //指定されたwSuiteMaskの少なくとも1つが含まれていななければならない private const byte VER_OR = 7; [System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Sequential)] public struct OSVERSIONINFOEX { public uint dwOSVersionInfoSize; public uint dwMajorVersion; public uint dwMinorVersion; public uint dwBuildNumber; public uint dwPlatformId; [System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public short wServicePackMajor; public short wServicePackMinor; public short wSuiteMask; public byte wProductType; public byte wReserved; } /// <summary> /// 現在のOSが指定されたバージョン以上かを調べる /// </summary> /// <param name="majorVersion"> /// メジャーバージョン番号。負の数の時は調べない。</param> /// <param name="minorVersion"> /// マイナーバージョン番号。負の数の時は調べない。</param> /// <param name="servicePackMajor"> /// サービスパックのメジャーバージョン番号。負の数の時は調べない。</param> /// <returns>現在のOSが指定されたバージョン以上ならTrue。</returns> public static bool IsWindowsVersionOrGreater( int majorVersion, int minorVersion, int servicePackMajor) { if (majorVersion < 0 && minorVersion < 0 && servicePackMajor < 0) { return true; } //lpVersionInfo、dwTypeMask、dwlConditionMaskを作成する OSVERSIONINFOEX osvi = new OSVERSIONINFOEX(); uint typeMask = 0; ulong conditionMask = 0; if (0 < majorVersion) { osvi.dwMajorVersion = (uint)majorVersion; conditionMask = VerSetConditionMask( conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); typeMask |= VER_MAJORVERSION; } if (0 < minorVersion) { osvi.dwMinorVersion = (uint)minorVersion; conditionMask = VerSetConditionMask( conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); typeMask |= VER_MINORVERSION; } if (0 < servicePackMajor) { osvi.wServicePackMajor = (short)servicePackMajor; conditionMask = VerSetConditionMask( conditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); typeMask |= VER_SERVICEPACKMAJOR; } //VerifyVersionInfoを呼び出す return VerifyVersionInfo(ref osvi, typeMask, conditionMask); }
MSDNの「Getting the System Version」によると、OSのフルのバージョン番号を取得するには、Kernel32.dllのようなシステムDLLのバージョンを取得するということです。この方法に従うなら、「ファイルのバージョン情報を取得する」で紹介しているFileVersionInfoクラスを使ってKernel32.dllのバージョンを取得すればよいということになりそうです。
ただ、OSのバージョンとKernel32.dllのバージョンが必ず一致するのかは、私には分かりません。
'kernel32.dllのパスを取得する Dim dllPath As String = System.IO.Path.Combine( _ System.Environment.SystemDirectory, "kernel32.dll") If System.IO.File.Exists(dllPath) Then 'FileVersionInfoを作成する Dim vi As System.Diagnostics.FileVersionInfo = _ System.Diagnostics.FileVersionInfo.GetVersionInfo(dllPath) 'バージョン番号 Console.WriteLine(vi.FileVersion) 'メジャーバージョン番号 Console.WriteLine(vi.FileMajorPart) 'マイナバージョン番号 Console.WriteLine(vi.FileMinorPart) End If
//kernel32.dllのパスを取得する string dllPath = System.IO.Path.Combine( System.Environment.SystemDirectory, "kernel32.dll"); if(System.IO.File.Exists(dllPath)) { //FileVersionInfoを作成する System.Diagnostics.FileVersionInfo vi = System.Diagnostics.FileVersionInfo.GetVersionInfo(dllPath); //バージョン番号 Console.WriteLine(vi.FileVersion); //メジャーバージョン番号 Console.WriteLine(vi.FileMajorPart); //マイナバージョン番号 Console.WriteLine(vi.FileMinorPart); }
レジストリの「HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion」(Windows 95系のOSの場合は「HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion」)キーにWindowsのバージョン情報があります。「CurrentVersion」に現在のバージョン([メジャーバージョン番号].[マイナーバージョン番号])、「CurrentBuild」にビルド番号、「ProductName」に製品名が格納されています。
ただ、レジストリにあるバージョンが常に正しいという保証があるかという点は、分かりません。
なおレジストリから値を取得する方法については、「レジストリへの書き込み、読み込み、削除を行う」をご覧ください。
'キーを開く Dim regkey As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.LocalMachine.OpenSubKey( _ "SOFTWARE\Microsoft\Windows NT\CurrentVersion", False) 'キーが存在しないときは、Windows 95系のキーを試す If regkey Is Nothing Then regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( _ "SOFTWARE\Microsoft\Windows\CurrentVersion", False) If regkey Is Nothing Then Return End If End If 'バージョンを取得する Dim versionString As String = _ DirectCast(regkey.GetValue("CurrentVersion"), String) '閉じる regkey.Close() '結果を表示する Console.WriteLine(versionString)
//キーを開く Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", false); //キーが存在しないときは、Windows 95系のキーを試す if (regkey == null) { regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion", false); if (regkey == null) { return; } } //バージョンを取得する string versionString = (string)regkey.GetValue("CurrentVersion"); //閉じる regkey.Close(); //結果を表示する Console.WriteLine(versionString);
前述したように、GetVersionExはWindows 8.1(およびWindows Server 2012 R2)からはdeprecatedとされ、何もしないと正しいバージョン(6.3)を返さず、間違ったバージョン(6.2)を返します。Environment.OSVersionプロパティも内部でGetVersionEx(あるいは、GetVersion)を使用していますので、やはり正しいバージョンを取得できません。
解決法としては、まずEnvironment.OSVersionプロパティやGetVersionExを使わない方法に切り替えることが考えられます。
どうしてもEnvironment.OSVersionプロパティやGetVersionExを使い続けなければならない場合は、解決法が「Operating system version changes in Windows 8.1 and Windows Server 2012 R2」にあります。これによると、アプリケーションがWindows 8.1をサポートしていることをマニフェストに明記していれば、GetVersionExでも正しいバージョンを取得できるということです。
具体的には、プロジェクトにまだマニフェストファイルがなければ、まずこれを作成します。Visual Studio 2008以上では、プロジェクトに新しい項目として「アプリケーションマニフェストファイル」を追加することで作成することができます。詳しくは、「マニフェストファイルを使用して、起動時に自動で管理者に昇格させるようにする」をご覧ください。
次に、マニフェストファイルのcompatibilityセクションにサポートするOSとしてWindows 8.1を追加します。Visual Studio 2013でアプリケーションマニフェストファイルを作成した時は以下のような内容になるため、必要なsupportedOSノードのコメントを解除するだけでOKです。
<?xml version="1.0" encoding="utf-8"?> <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC マニフェスト オプション Windows のユーザー アカウント制御のレベルを変更するには、 requestedExecutionLevel ノードを以下のいずれかで置換します。 <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> requestedExecutionLevel ノードを指定すると、ファイルおよびレジストリの仮想化は無効になります。 旧バージョンとの互換性のためにファイルおよびレジストリの仮想化を 使用する場合は、requestedExecutionLevel ノードを削除します。 --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!--このアプリケーションが動作するように設計されている、Windows のすべてのバージョンの一覧。 Windows は最も互換性の高い環境を自動的に選択します。--> <!--アプリケーションが Windows Vista で動作するように設計されている場合は、次の supportedOS ノードのコメントを解除します--> <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>--> <!-- アプリケーションが Windows 7 で動作するように設計されている場合は、次の supportedOS ノードのコメントを解除します。--> <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>--> <!--アプリケーションが Windows 8 で動作するように設計されている場合は、次の supportedOS ノードのコメントを解除します--> <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>--> <!-- アプリケーションが Windows 8.1 で動作するように設計されている場合は、次の supportedOS ノードのコメントを解除してください--> <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>--> </application> </compatibility> <!-- Windows のコモン コントロールとダイアログのテーマを有効にします (Windows XP 以降) --> <!-- <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency>--> </asmv1:assembly>
Visual Studio 2015では、アプリケーションマニフェストファイルにWindows 10用のsupportedOSノードも記述されています。Windows 10用のsupportedOSノードは、「<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />」です。
MSDNには、「Targeting your application for Windows」にアプリケーションマニフェストファイルのサンプルがあります。
.NET Framework 2.0からは、OperatingSystem.ServicePackプロパティでサービスパックのバージョンを取得できます。また、OperatingSystem.VersionStringプロパティでもサービスパック情報の付いた文字列を取得できます。例えば、Windows XP SP2の場合は、ServicePackプロパティが「Service Pack 2」、VersionStringプロパティが「Microsoft Windows NT 5.1.2600 Service Pack 2」のようになります。
WMIのWin32_OperatingSystemクラスを使用した時は、CSDVersionプロパティで「Service Pack 2」のように取得できます。また、ServicePackMajorVersionプロパティでサービスパックのメジャーバージョン番号を、ServicePackMinorVersionプロパティでマイナーバージョン番号を取得できます。「Service Pack 2」の場合は、メジャーバージョン番号が2、マイナーバージョン番号が0です。
GetVersionExなどを使ってOSVERSIONINFOEXで取得した時は、szCSDVersionフィールドにサービスパックの情報が「Service Pack 2」のように入ります。また、サービスパックのメジャーバージョン番号がwServicePackMajor、マイナーバージョン番号がwServicePackMinorに入ります。
OSがサーバーかどうかは、Environment.OSVersionプロパティでは分かりません。
WMIを使用した方法ならば、Win32_OperatingSystemクラスのProductTypeプロパティで分かります。ProductTypeプロパティが1ならば、ワークステーション(Windows 8, Windows 7, Windows Vistaなど)です。それ以外ならば、OSはサーバー(Windows Server 2012, Windows Server 2008 R2, Windows Server 2008など)です(ProductTypeが2の時は、ドメインコントローラです)。
また、GetVersionExなどを使ってOSVERSIONINFOEXで取得したのであれば、wProductTypeフィールドによって同じ判断(1以外ならサーバー)ができます。
「c# - Determining if the program is running on Windows Server」によると、サーバーかどうかを調べるだけならば、IsOS functionを使用することもできます。
<System.Runtime.InteropServices.DllImport("shlwapi.dll", _ SetLastError:=True, EntryPoint:="#437")> _ Private Shared Function IsOS(os As Integer) As Boolean End Function Private Const OS_ANYSERVER As Integer = 29 ''' <summary> ''' 現在のOSがサーバーかどうか調べる ''' </summary> ''' <returns>サーバーならTrue。それ以外はFalse。</returns> Public Shared Function IsWindowsServer() As Boolean Return IsOS(OS_ANYSERVER) End Function
[System.Runtime.InteropServices.DllImport("shlwapi.dll", SetLastError = true, EntryPoint = "#437")] private static extern bool IsOS(int os); private const int OS_ANYSERVER = 29; /// <summary> /// 現在のOSがサーバーかどうか調べる /// </summary> /// <returns>サーバーならTrue。それ以外はFalse。</returns> public static bool IsWindowsServer() { return IsOS(OS_ANYSERVER); }
「アプリケーションが64ビットで動いているか調べる」で説明しています。