DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

アプリケーションが64ビットで動いているか調べる

IntPtr.Sizeを使う

アプリケーションのプロセスが32ビットで動作しているか、64ビットで動作しているか(32ビットCLR上で実行されているか、64ビットCLR上で実行されているか)を判断するには、IntPtr.Sizeプロパティを使うと簡単です。IntPtr.Sizeが4ならば32ビット、8ならば64ビットで動作しています。

VB.NET
コードを隠すコードを選択
If IntPtr.Size = 4 Then
    Console.WriteLine("32ビットで動作しています")
ElseIf IntPtr.Size = 8 Then
    Console.WriteLine("64ビットで動作しています")
End If
C#
コードを隠すコードを選択
if (IntPtr.Size == 4)
{
    Console.WriteLine("32ビットで動作しています");
}
else if (IntPtr.Size == 8)
{
    Console.WriteLine("64ビットで動作しています");
}

.NET Framework 4.0以降で、Is64BitProcessプロパティを使う

.NET Framework 4.0からは、Environment.Is64BitProcessプロパティを使って現在のプロセスが64ビットかどうかを調べることができます。このプロパティは、Windows XP SP3以降で使用できます。

VB.NET
コードを隠すコードを選択
If System.Environment.Is64BitProcess Then
    Console.WriteLine("64ビットで動作しています")
End If
C#
コードを隠すコードを選択
if (System.Environment.Is64BitProcess)
{
    Console.WriteLine("64ビットで動作しています");
}

OSが64ビットか調べる

アプリケーションのプロセスが32ビットで動作していたとしても、OSが32ビットとは限りません。プラットフォームターゲット(/platformコンパイラオプション)を「x86」にしているならば、64ビット版Windows OSのWOW64によって、32ビットプロセスで動作している可能性があります。よって上記の方法でOSが64ビットか32ビットかを調べることはできません。

以下に、OSが64ビットか32ビットかを調べる方法を幾つか紹介します。

.NET Framework 4.0以降で、Is64BitOperatingSystemプロパティを使う

.NET Framework 4.0からは、Environment.Is64BitOperatingSystemプロパティを使ってOSが64ビットかどうかを調べることができます。このプロパティは、Windows XP SP3以降で使用できます。

VB.NET
コードを隠すコードを選択
If System.Environment.Is64BitOperatingSystem Then
    Console.WriteLine("64ビットOSです。")
End If
C#
コードを隠すコードを選択
if (System.Environment.Is64BitOperatingSystem)
{
    Console.WriteLine("64ビットOSです。");
}

IsWow64Processを使う

Win32 APIのIsWow64Process関数を使うことによって、プロセスがWOW64上で動作しているかを調べることができます。

IsWow64ProcessはWindows XP SP2以降でしか使用できないため、それより前のOSでIsWow64Processを呼び出さないようにする工夫が必要です。例えば、「OSのバージョンを取得する」で紹介した方法でOSの種類を調べたり、GetProcAddress関数を使ってIsWow64Processが存在するか調べる方法などが考えられます。

以下にIsWow64Processを使ってOSが64ビットかを調べる例(Is64BitOSメソッドとしました)を紹介します。ここではGetProcAddressを使ってIsWow64Processが使えるかを調べています。

VB.NET
コードを隠すコードを選択
'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
C#
コードを隠すコードを選択
//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 により、プロセッサの種類を知ることができます。環境変数 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 を使用した例を示します。

VB.NET
コードを隠すコードを選択
'現在のプロセスにおける環境変数"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
C#
コードを隠すコードを選択
//現在のプロセスにおける環境変数"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では使用できません。

VB.NET
コードを隠すコードを選択
'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
C#
コードを隠すコードを選択
//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"の値を取得する例を示します。

VB.NET
コードを隠すコードを選択
'レジストリを開く
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()
C#
コードを隠すコードを選択
//レジストリを開く
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を使う

WMIでは、Win32_Processor classのAddressWidthプロパティを使うと、OSが32ビットか64ビットか調べることができます。

以下に例を示します。なおこのコードを実行するには、参照設定に「System.Management.dll」を追加する必要があります。

VB.NET
コードを隠すコードを選択
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()
C#
コードを隠すコードを選択
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以上でしか使えないようです。

VB.NET
コードを隠すコードを選択
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
C#
コードを隠すコードを選択
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です。");
}

ここで紹介した以外にも、いろいろな方法が考えられると思います。いい方法をご存知でしたら、ぜひ教えてください。

  • 履歴:
  • 2010/11/11 Is64BitOSメソッドの間違いを修正。
  • 2016/9/4 WMIを使う方法で、Win32_ProcessorのクラスのArchitectureではなく、AddressWidthを使用する方法に変更。Win32_OperatingSystemを使う方法を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、レジストリへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。