【问题标题】:How to determine programmatically whether a particular process is 32-bit or 64-bit如何以编程方式确定特定进程是 32 位还是 64 位
【发布时间】:2010-12-29 12:43:51
【问题描述】:

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

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

【问题讨论】:

  • 请始终将语言作为标签;我现在将在这篇文章中进行更改。 :-)
  • 请说明您是想知道当前进程是64位还是正在查询另一个进程?

标签: c# process 32bit-64bit


【解决方案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);
    }
}

【讨论】:

  • (Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) 这就是为什么微软必须创建版本谎言兼容性垫片 - 以解决此类代码中的错误。当 Windows Vista (6.0) 出现时会发生什么?然后人们就因为微软制作了 Windows 7 版本 6.1 而不是 7.0 而诟病,它修复了许多应用程序兼容的错误。
  • 我认为函数名 IsWin64 有点误导。如果 32 位进程在 x64 操作系统下运行,则返回 true。
  • 为什么使用processHandle = Process.GetProcessById(process.Id).Handle; 而不仅仅是processHandle = process.Handle;
  • @JonathonReinhart 这不只是一个好问题。我不知道。从以一种方式做事到另一种方式做事的转变一定是退化的。感谢您找到它!
  • 这个答案是不正确的;并且在出错的情况下返回 false 而不是引发异常是一个非常糟糕的设计。
【解决方案2】:

如果您使用的是 .Net 4.0,它是当前流程的单线:

Environment.Is64BitProcess

请参阅 Environment.Is64BitProcessProperty (MSDN)。

【讨论】:

  • 可以发一下Is64BitProcess的代码吗?也许我可以使用它来确定我是否作为 64 位进程运行。
  • @Ian,我怀疑 Sam 是否会被法律允许在这个论坛上发布 MS 代码。我不确定他们的参考许可证的确切内容,但我很确定它禁止在任何地方复制代码。
  • @Ian 有人为您完成了这项工作:stackoverflow.com/questions/336633/…
  • OP专门要求查询另一个进程,而不是当前进程。
  • 请注意,Microsoft 确实 发布了Is64BitProcess (referencesource.microsoft.com/#mscorlib/system/environment.cs) 的代码。但是,它只是一个硬编码的返回语句,由编译符号控制。
【解决方案3】:

选择的答案不正确,因为它不符合要求。它检查进程是否是在 x64 操作系统上运行的 x86 进程;因此它将为 x64 操作系统上的 x64 进程返回“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);
}

【讨论】:

  • Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86" 对于 32 位进程将始终返回 true。如果支持.NET4,最好使用System.Environment.Is64BitOperatingSystem
【解决方案4】:

您可以检查指针的大小以确定它是 32 位还是 64 位。

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

【讨论】:

  • 在首次发布此答案时还不是很清楚,但 OP 想知道如何查询 另一个 进程而不是当前进程。
【解决方案5】:
[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;
}

【讨论】:

  • OP专门询问如何查询另一个进程,而不是当前进程。
【解决方案6】:

这是单行检查。

bool is64Bit = IntPtr.Size == 8;

【讨论】:

  • OP专门询问如何查询另一个进程,而不是当前进程。
【解决方案7】:

我喜欢用这个:

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\";

【讨论】:

  • 64bit OS Machine 中的 32bit 进程呢?
  • Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)代替硬编码`C:\Program Files`真的那么难吗?
  • 永远不要硬编码“程序文件”,因为它是一个可本地化的字符串。 Αρχεία Εφαρμογών、Arquivos de Programas 等。
猜你喜欢
  • 2011-05-04
  • 1970-01-01
  • 2012-01-25
  • 2011-04-04
  • 2011-04-16
  • 2017-09-04
相关资源
最近更新 更多