アプリケーションのプロセスが32ビットで動作しているか、64ビットで動作しているか(32ビットCLR上で実行されているか、64ビットCLR上で実行されているか)を判断するには、IntPtr.Sizeプロパティを使うと簡単です。IntPtr.Sizeが4ならば32ビット、8ならば64ビットで動作しています。
If IntPtr.Size = 4 Then Console.WriteLine("32ビットで動作しています") ElseIf IntPtr.Size = 8 Then Console.WriteLine("64ビットで動作しています") End If
if (IntPtr.Size == 4) { Console.WriteLine("32ビットで動作しています"); } else if (IntPtr.Size == 8) { Console.WriteLine("64ビットで動作しています"); }
.NET Framework 4.0からは、Environment.Is64BitProcessプロパティを使って現在のプロセスが64ビットかどうかを調べることができます。このプロパティは、Windows XP SP3以降で使用できます。
If System.Environment.Is64BitProcess Then Console.WriteLine("64ビットで動作しています") End If
if (System.Environment.Is64BitProcess)
{
Console.WriteLine("64ビットで動作しています");
}
アプリケーションのプロセスが32ビットで動作していたとしても、OSが32ビットとは限りません。プラットフォームターゲット(/platformコンパイラオプション)を「x86」にしているならば、64ビット版Windows OSのWOW64によって、32ビットプロセスで動作している可能性があります。よって上記の方法でOSが64ビットか32ビットかを調べることはできません。
以下に、OSが64ビットか32ビットかを調べる方法を幾つか紹介します。
.NET Framework 4.0からは、Environment.Is64BitOperatingSystemプロパティを使ってOSが64ビットかどうかを調べることができます。このプロパティは、Windows XP SP3以降で使用できます。
If System.Environment.Is64BitOperatingSystem Then Console.WriteLine("64ビットOSです。") End If
if (System.Environment.Is64BitOperatingSystem)
{
Console.WriteLine("64ビットOSです。");
}
Win32 APIのIsWow64Process関数を使うことによって、プロセスがWOW64上で動作しているかを調べることができます。
IsWow64ProcessはWindows XP SP2以降でしか使用できないため、それより前のOSでIsWow64Processを呼び出さないようにする工夫が必要です。例えば、「OSのバージョンを取得する」で紹介した方法でOSの種類を調べたり、GetProcAddress関数を使ってIsWow64Processが存在するか調べる方法などが考えられます。
以下にIsWow64Processを使ってOSが64ビットかを調べる例(Is64BitOSメソッドとしました)を紹介します。ここではGetProcAddressを使ってIsWow64Processが使えるかを調べています。
'Imports System.Runtime.InteropServices <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _ Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr End Function <DllImport("kernel32", CharSet:=CharSet.Ansi, ExactSpelling:=True)> _ Private Shared Function GetProcAddress(ByVal hModule As IntPtr, _ ByVal procName As String) As IntPtr End Function <DllImport("kernel32.dll")> _ Private Shared Function IsWow64Process(ByVal hProcess As IntPtr, _ ByRef lpSystemInfo As Boolean) _ As <MarshalAs(UnmanagedType.Bool)> Boolean End Function '現在のプロセスがWOW32上で動作しているか調べる Public Function IsWow64() As Boolean 'IsWow64Processが使えるか調べる Dim wow64Proc As IntPtr = GetProcAddress(GetModuleHandle("Kernel32.dll"), _ "IsWow64Process") If wow64Proc <> IntPtr.Zero Then 'IsWow64Processを呼び出す Dim ret As Boolean If IsWow64Process(System.Diagnostics.Process.GetCurrentProcess().Handle, ret) Then Return ret End If End If Return False End Function 'OSが64ビットか調べる Public Function Is64BitOS() As Boolean If IntPtr.Size = 4 Then If IsWow64() Then 'OSは64ビットです Return True Else 'OSは32ビットです Return False End If ElseIf IntPtr.Size = 8 Then 'OSは64ビットです Return True End If Return False End Function
//using System.Runtime.InteropServices; [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo); //現在のプロセスがWOW32上で動作しているか調べる public bool IsWow64() { //IsWow64Processが使えるか調べる IntPtr wow64Proc = GetProcAddress(GetModuleHandle("Kernel32.dll"), "IsWow64Process"); if (wow64Proc != IntPtr.Zero) { //IsWow64Processを呼び出す bool ret; if (IsWow64Process(System.Diagnostics.Process.GetCurrentProcess().Handle, out ret)) { return ret; } } return false; } //OSが64ビットか調べる public bool Is64BitOS() { if (IntPtr.Size == 4) { if (IsWow64()) { //OSは64ビットです return true; } else { //OSは32ビットです return false; } } else if (IntPtr.Size == 8) { //OSは64ビットです return true; } return false; }
補足:GetNativeSystemInfo関数やGetSystemWow64Directory関数を使う方法もあります。
環境変数 PROCESSOR_ARCHITECTURE により、プロセッサの種類を知ることができます。環境変数 PROCESSOR_ARCHITECTURE は、例えば、32ビットであれば"x86"、64ビットであれば"AMD64"や"IA64"といった値になります。
しかし、「WOW64 実装の詳細 (Windows)」によると、WOW64上の32ビットプロセスでは、PROCESSOR_ARCHITECTURE に"x86"が設定されます。この時、本来の PROCESSOR_ARCHITECTURE の値は、PROCESSOR_ARCHITEW6432 に設定されます。なお PROCESSOR_ARCHITEW6432 はWOW64でのみ使用されます。
以下に、環境変数 PROCESSOR_ARCHITECTURE と PROCESSOR_ARCHITEW6432 を使用した例を示します。
'現在のプロセスにおける環境変数"PROCESSOR_ARCHITECTURE"の値を取得 Dim procArch As String = _ System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") If procArch Is Nothing OrElse procArch = "x86" Then '環境変数"PROCESSOR_ARCHITEW6432"の値を取得 Dim pa6432 As String = _ System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432") If pa6432 Is Nothing OrElse pa6432 = "x86" Then Console.WriteLine("32ビットOSです。") Else Console.WriteLine("64ビットOSです。") End If Else Console.WriteLine("64ビットOSです。") End If
//現在のプロセスにおける環境変数"PROCESSOR_ARCHITECTURE"の値を取得 string procArch = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); if (procArch == null || procArch == "x86") { //環境変数"PROCESSOR_ARCHITEW6432"の値を取得 string pa6432 = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"); if (pa6432 == null || pa6432 == "x86") { Console.WriteLine("32ビットOSです。"); } else { Console.WriteLine("64ビットOSです。"); } } else { Console.WriteLine("64ビットOSです。"); }
または、Environment.GetEnvironmentVariableメソッドの2番目のパラメータを EnvironmentVariableTarget.Machine にすることにより、ローカルコンピュータを使用するすべてのユーザーに関連した環境変数の値を取得する方法もあります。ただしこの方法は、.NET Framework 1.1以前または、Windows 9x系OSでは使用できません。
'Windows NT系OSか調べる If System.Environment.OSVersion.Platform = System.PlatformID.Win32NT Then 'ローカルコンピュータの環境変数"PROCESSOR_ARCHITECTURE"の値を取得 Dim procArch As String = System.Environment.GetEnvironmentVariable( _ "PROCESSOR_ARCHITECTURE", System.EnvironmentVariableTarget.Machine) If procArch Is Nothing OrElse procArch = "x86" Then Console.WriteLine("32ビットOSです。") Else Console.WriteLine("64ビットOSです。") End If Else Console.WriteLine("32ビットOSです。") End If
//Windows NT系OSか調べる if (System.Environment.OSVersion.Platform == System.PlatformID.Win32NT) { //ローカルコンピュータの環境変数"PROCESSOR_ARCHITECTURE"の値を取得 string procArch = System.Environment.GetEnvironmentVariable( "PROCESSOR_ARCHITECTURE", System.EnvironmentVariableTarget.Machine); if (procArch == null || procArch == "x86") { Console.WriteLine("32ビットOSです。"); } else { Console.WriteLine("64ビットOSです。"); } } else { Console.WriteLine("32ビットOSです。"); }
.NET Framework 1.1以前またはWindows 9x系OSであっても、レジストリから直接値を取得すれば、同じことができます。以下に、レジストリから直接環境変数"PROCESSOR_ARCHITECTURE"の値を取得する例を示します。
'レジストリを開く Dim key As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.LocalMachine.OpenSubKey( _ "System\CurrentControlSet\Control\Session Manager\Environment") '"PROCESSOR_ARCHITECTURE"の値を取得 Dim procArch As String = DirectCast(key.GetValue("PROCESSOR_ARCHITECTURE"), String) '閉じる key.Close()
//レジストリを開く Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( @"System\CurrentControlSet\Control\Session Manager\Environment"); //"PROCESSOR_ARCHITECTURE"の値を取得 string procArch = (string)key.GetValue("PROCESSOR_ARCHITECTURE"); //閉じる key.Close();
補足:上記以外に、環境変数"ProgramFiles(x86)"が存在すれば64ビットなどの方法もあります。
WMIでは、Win32_Processor classのAddressWidthプロパティを使うと、OSが32ビットか64ビットか調べることができます。
以下に例を示します。なおこのコードを実行するには、参照設定に「System.Management.dll」を追加する必要があります。
Dim mo As New System.Management.ManagementObject( _ "Win32_Processor.DeviceID='CPU0'") Dim addWidth As Integer = Convert.ToInt32(mo("AddressWidth")) If addWidth = 32 Then Console.WriteLine("32ビットOSです。") ElseIf addWidth = 64 Then Console.WriteLine("64ビットOSです。") End If mo.Dispose()
System.Management.ManagementObject mo = new System.Management.ManagementObject("Win32_Processor.DeviceID='CPU0'"); ushort addWidth = (ushort)mo["AddressWidth"]; if (addWidth == 32) { Console.WriteLine("32ビットOSです。"); } else if (addWidth == 64) { Console.WriteLine("64ビットOSです。"); } mo.Dispose();
また、Win32_OperatingSystem classのOSArchitectureプロパティでもOSが何ビットなのかが分かります。この方法は、Windows Vista、Windows Server 2008以上でしか使えないようです。
Dim mc As New System.Management.ManagementClass("Win32_OperatingSystem") Dim moc As System.Management.ManagementObjectCollection = mc.GetInstances() Dim osArch As String = "" For Each mo As System.Management.ManagementObject In moc osArch = DirectCast(mo("OSArchitecture"), String) Next If osArch.IndexOf("32") >= 0 Then '32ビット Console.WriteLine("32ビットOSです。") ElseIf osArch.IndexOf("64") >= 0 Then '64ビット Console.WriteLine("64ビットOSです。") End If
System.Management.ManagementClass mc = new System.Management.ManagementClass("Win32_OperatingSystem"); System.Management.ManagementObjectCollection moc = mc.GetInstances(); string osArch = ""; foreach (System.Management.ManagementObject mo in moc) { osArch = (string)mo["OSArchitecture"]; } if (osArch.IndexOf("32") >= 0) { //32ビット Console.WriteLine("32ビットOSです。"); } else if (osArch.IndexOf("64") >= 0) { //64ビット Console.WriteLine("64ビットOSです。"); }
ここで紹介した以外にも、いろいろな方法が考えられると思います。いい方法をご存知でしたら、ぜひ教えてください。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。