特定のプロセスが32ビットか64ビットかをプログラムで判断する方法


102

C#アプリケーションは、特定のアプリケーション/プロセス(注:現在のプロセスではない)が32ビットまたは64ビットモードで実行されているかどうかをどのように確認できますか?

たとえば、「abc.exe」という名前で、またはプロセスID番号に基づいて、特定のプロセスをクエリしたい場合があります。


常にタグとして言語を入れてください。私はこの記事でこれを変更します。:-)
Dean J、

3
現在のプロセスが64ビットかどうかを知りたいのか、それとも別のプロセスに問い合わせているのかを明確にしてください。
Mehrdad Afshari、

回答:


177

私が見た中で最も興味深い方法の1つはこれです。

if (IntPtr.Size == 4)
{
    // 32-bit
}
else if (IntPtr.Size == 8)
{
    // 64-bit
}
else
{
    // The future is now!
}

他のプロセスが64ビットエミュレーター(WOW64)で実行されているかどうかを確認するには、次のコードを使用します。

namespace Is64Bit
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    internal static class Program
    {
        private static void Main()
        {
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    Console.WriteLine(p.ProcessName + " is " + (p.IsWin64Emulator() ? string.Empty : "not ") + "32-bit");
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode != 0x00000005)
                    {
                        throw;
                    }
                }
            }

            Console.ReadLine();
        }

        private static bool IsWin64Emulator(this Process process)
        {
            if ((Environment.OSVersion.Version.Major > 5)
                || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1)))
            {
                bool retVal;

                return NativeMethods.IsWow64Process(process.Handle, out retVal) && retVal;
            }

            return false; // not on 64-bit Windows Emulator
        }
    }

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
    }
}

8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) そしてそれが、マイクロソフトがバージョンライ互換性シムを作成しなければならない理由です-そのようなコードのバグを回避するため。Windows Vista(6.0)が出たらどうなりますか?そして人々は、7.0ではなくWindows 7バージョン6.1を作成することでMicrosoftを口当たりにし、多くのアプリ互換バグを修正します。
Ian Boyd

4
関数名IsWin64は少し誤解を招くと思います。32ビットプロセスがx64 OSで実行されている場合、trueを返します。
Denis The Menace

2
なぜprocessHandle = Process.GetProcessById(process.Id).Handle;単にではなく使用するのprocessHandle = process.Handle;ですか?
Jonathon Reinhart 2014年

1
@JonathonReinhartはそれだけで良い質問ではありません。何も思いつきません。それは、物事をある方法から別の方法に切り替えることからの痕跡だったに違いありません。見つけてくれてありがとう!
Jesse C. Slicer 2014年

1
この答えは正しくありません。エラーが発生した場合に例外を発生させる代わりにfalseを返すのは非常に悪い設計です。
user626528

141

.Net 4.0を使用している場合、これは現在のプロセスのワンライナーです。

Environment.Is64BitProcess

Environment.Is64BitProcessProperty(MSDN)を参照してください。


2
のコードを投稿してもらえますIs64BitProcessか?おそらく、64ビットプロセスとして実行されているかどうかを判断するために、この機能を使用できます。
Ian Boyd

1
@イアン、サムが合法的にこのフォーラムにMSコードを投稿することは許されないだろう。参照ライセンスの正確な内容はわかりませんが、どこでもコードの複製を禁止していると確信しています。
ProfK 2011年

3
@Ian誰かがあなたのためにその仕事をしていますstackoverflow.com/questions/336633/...
ロバート・マックリーン

4
OP は、現在のプロセスではなく、別のプロセスを照会するように特別に要求しました。
ハリージョンストン、

1
Microsoft Is64BitProcessreferencesource.microsoft.com/#mscorlib/system/environment.cs)のコードを投稿したことに注意してください。ただし、これはコンパイルシンボルによって制御される、ハードコードされたreturnステートメントにすぎません。
ブライアン

20

選択された回答は、要求された内容を実行しないため、不正解です。プロセスがx64 OSで実行されているx86プロセスであるかどうかを確認します。そのため、x64 OSのx64プロセスまたはx86 OSで実行されているx86プロセスの場合は「false」を返します。
また、エラーを正しく処理しません。

これはより正しい方法です:

internal static class NativeMethods
{
    // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
    public static bool Is64Bit(Process process)
    {
        if (!Environment.Is64BitOperatingSystem)
            return false;
        // if this method is not available in your version of .NET, use GetNativeSystemInfo via P/Invoke instead

        bool isWow64;
        if (!IsWow64Process(process.Handle, out isWow64))
            throw new Win32Exception();
        return !isWow64;
    }

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
}

1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"32ビットプロセスでは常にtrueを返します。System.Environment.Is64BitOperatingSystem
.NET4

10

ポインタのサイズを確認して、32ビットか64ビットかを判断できます。

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();

6
この回答が最初に投稿されたとき、それはあまり明確ではありませんでしたが、OP は現在のプロセスではなく別のプロセスをクエリする方法を知りたがっていました。
ハリージョンストン、

3
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);

public static bool Is64Bit()
{
    bool retVal;

    IsWow64Process(Process.GetCurrentProcess().Handle, out retVal);

    return retVal;
}

5
OP は、現在のプロセスではなく、別のプロセスをクエリする方法を具体的に尋ねました。
ハリージョンストン


0

私はこれを使いたいです:

string e = Environment.Is64BitOperatingSystem

このようにして、簡単に書き込むことができるファイルを検索または検証する必要がある場合:

string e = Environment.Is64BitOperatingSystem

       // If 64 bit locate the 32 bit folder
       ? @"C:\Program Files (x86)\"

       // Else 32 bit
       : @"C:\Program Files\";

13
64ビットOSマシンの32ビットプロセスはどうですか?
Kiquenet 2012

3
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)`C:\ Program Files`をハードコーディングする代わりに使うのは本当に難しいですか?
Luaan、2015年

2
ローカライズ可能な文字列であるため、「プログラムファイル」をハードコードしないでください。ΑρχείαΕφαρμογών、Arquivos de Programasなど
stevieg 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.