如何以编程方式确定特定进程是32位还是64位


102

我的C#应用​​程序如何检查特定的应用程序/进程(注意:不是当前进程)是以32位还是64位模式运行的?

例如,我可能想通过名称(即“ abc.exe”)或基于进程ID号来查询特定进程。


请始终将语言标记为标签;我现在将在这篇文章中对此进行更改。:-)
Dean J

3
请说明您是否想知道当前进程是64位还是要查询另一个进程?
Mehrdad Afshari

Answers:


177

我见过的一种更有趣的方式是:

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)发行时会怎样?然后人们对微软制造Windows 7版本6.1而不是7.0的口口相传,它修复了许多与应用程序兼容的错误。
伊恩·博伊德

4
我认为函数名称IsWin64有点误导。如果32位进程在x64 OS下运行,则返回true。
丹尼斯的威胁

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位进程运行。
伊恩·博伊德

1
@Ian,我怀疑Sam是否会合法地在此论坛上发布MS代码。我不确定他们的参考许可证的确切内容,但是我很确定它禁止在任何地方复制代码。
ProfK

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支持
Aizzat Suhardi

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

3
真的很难用它Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)代替硬编码C:\ Program Files`吗?
a安2015年

2
切勿对“程序文件”进行硬编码,因为它是可本地化的字符串。ΑρχείαΕφαρμογών,Programas等
节目
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.