วิธีการตรวจสอบแพลตฟอร์ม Windows 64 บิตด้วย. NET


268

ในแอปพลิเคชัน. NET 2.0 C # ฉันใช้รหัสต่อไปนี้เพื่อตรวจสอบแพลตฟอร์มระบบปฏิบัติการ:

string os_platform = System.Environment.OSVersion.Platform.ToString();

ส่งคืน "Win32NT" ปัญหาคือมันส่งกลับ "Win32NT" แม้ในขณะที่ทำงานบน Windows Vista 64- บิต

มีวิธีอื่นที่จะทราบแพลตฟอร์มที่ถูกต้อง (32 หรือ 64 บิต) หรือไม่?

โปรดทราบว่าควรตรวจจับ 64 บิตเมื่อเรียกใช้เป็นแอปพลิเคชัน 32 บิตใน Windows 64 บิต

คำตอบ:


200

IntPtr.Size จะไม่ส่งคืนค่าที่ถูกต้องหากทำงานใน 32 บิต. NET Framework 2.0 บน Windows 64 บิต (จะกลับมาเป็น 32- บิต)

ดังที่ Microsoft อธิบาย Raymond Chen คุณต้องตรวจสอบก่อนว่าการทำงานในกระบวนการ 64 บิตหรือไม่ (ฉันคิดว่าใน. NET คุณสามารถทำได้โดยการตรวจสอบ IntPtr.Size) และหากคุณกำลังทำงานในกระบวนการ 32 บิตคุณยังคง ต้องเรียกใช้ฟังก์ชัน Win API IsWow64Process หากสิ่งนี้กลับเป็นจริงคุณกำลังทำงานในกระบวนการ 32 บิตบน Windows 64 บิต

Raymond Chen ของ Microsoft: วิธีการตรวจสอบโดยทางโปรแกรมว่าคุณใช้ Windows 64 บิตหรือไม่

ทางออกของฉัน:

static bool is64BitProcess = (IntPtr.Size == 8);
static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();

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

public static bool InternalCheckIsWow64()
{
    if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
        Environment.OSVersion.Version.Major >= 6)
    {
        using (Process p = Process.GetCurrentProcess())
        {
            bool retVal;
            if (!IsWow64Process(p.Handle, out retVal))
            {
                return false;
            }
            return retVal;
        }
    }
    else
    {
        return false;
    }
}

7
เมื่อทำงานบนระบบปฏิบัติการ 32 บิตการเรียกใช้ IsWow64Process จะมีข้อผิดพลาดเนื่องจากรายการนั้นหายไปจาก kernel32.dll คุณควรตรวจสอบวิธีแก้ปัญหาที่แสดงจาก codeplex ที่1code.codeplex.com/SourceControl/changeset/view/39074#842775นอกจากนี้ฉันยังมีวิธีแก้ไขตามรหัสที่แสดงไว้ที่ด้านล่างของหน้านี้ซึ่งใช้วิธีการขยายหากคุณสนใจ การใช้รหัสซ้ำ
dmihailescu

7
แนะนำให้ใช้ IsWow64Process กับ Win XP SP2 รหัสนี้ใช้งานได้ดีถ้าคุณต้องการ XP SP2 หรือรุ่นที่ใหม่กว่า
Marc

3
@dmihailescu คุณสามารถใช้ DoesWin32MethodExist ก่อนที่จะเรียก IsWow64Process ซึ่งเป็นสิ่งที่การใช้งาน. net 4.0 ของ is64BitOperatingSystem
noobish

4
โซลูชันของคุณจะส่งคืนค่าที่ถูกต้องบน MacBook Pro ด้วย Intel i7-3720QM ไมโครโปรเซสเซอร์ที่ใช้ Bootcamp โดยใช้พาร์ติชัน Widows 7 Ultimate +1
Mark Kram

11
FYI: เริ่มต้นด้วย. Net 4.0 คุณสามารถตรวจสอบSystem.Environment.Is64BitOperatingSystemได้ คุณสามารถแก้ไขสิ่งนี้เป็นคำตอบของคุณหรือให้สิทธิ์ฉันในการแก้ไขเป็นคำตอบของคุณ?
Joel Coehoorn

241

.NET 4 มีสองคุณสมบัติใหม่ในชั้นสิ่งแวดล้อมIs64BitProcessและIs64BitOperatingSystem น่าสนใจถ้าคุณใช้ Reflector คุณจะเห็นว่ามีการใช้งานแตกต่างกันใน mscorlib รุ่น 32 บิตและ 64 บิต รุ่น 32 บิตส่งคืนค่าเท็จสำหรับ Is64BitProcess และเรียก IsWow64Process ผ่าน P / เรียกใช้สำหรับ Is64BitOperatingSystem รุ่น 64 บิตจะคืนค่าจริงทั้งคู่


5
แทนที่จะเป็น Reflector ทำไมไม่เพียงดาวน์โหลดที่มา จากนั้นคุณจะได้รับความคิดเห็นและ "บันทึก" อื่น ๆ
AMissico

3
ตามแหล่งอ้างอิงมันทำอะไรเช่นนี้: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(หลอกรหัส)
พหุนาม

5
ดี หากผู้ใช้ใช้. NET 4.0 นี่เป็นคำตอบที่ถูกต้องแน่นอน (เช่น Environment.Is64BitOperatingSystem) - คุณสมบัติ FYI ไม่ปรากฏว่ามีอยู่ใน. NET 3.5
BrainSlugs83

4
นี่ไม่ได้ตอบคำถามที่พูดโดยเฉพาะ. Net 2.0
abbottdev

.NET Core ได้รับการเผยแพร่ภายใต้ลิขสิทธิ์ของ MIT ซึ่งหมายความว่าคุณสามารถอ่านซอร์สโค้ดสำหรับIs64BitProcessและIs64BitOperatingSystem(ลิงก์สำหรับเวอร์ชั่น 2.0)
Cristian Ciupitu


51

นี่เป็นเพียงการนำไปใช้ในสิ่งที่แนะนำโดย Bruno Lopez แต่ใช้งานได้กับ Win2k + WinXP service pack ทั้งหมด เพิ่งคิดว่าฉันจะโพสต์ไว้เพื่อคนอื่น ๆ จะไม่กลิ้งมันด้วยมือ (จะมีการโพสต์เป็นความคิดเห็น แต่ฉันเป็นผู้ใช้ใหม่!)

[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr LoadLibrary(string libraryName);

[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);

private delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process);

public static bool IsOS64Bit()
{
    if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
    {
        return true;
    }
    else
    {
        return false;
    }
}

private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
{
  IntPtr handle = LoadLibrary("kernel32");

  if ( handle != IntPtr.Zero)
  {
    IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");

    if (fnPtr != IntPtr.Zero)
    {
      return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate));
    }
  }

  return null;
}

private static bool Is32BitProcessOn64BitProcessor()
{
  IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();

  if (fnDelegate == null)
  {
    return false;
  }

  bool isWow64;
  bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64);

  if (retVal == false)
  {
    return false;
  }

  return isWow64;
}

49

คำตอบทั้งหมดคือ (นำมาจากทั้งคำว่า stefan-mg, ripper234 และคำตอบของ BobbyShaftoe):

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

    private bool Is64Bit()
    {
        if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private bool Is32BitProcessOn64BitProcessor()
    {
        bool retVal;

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

        return retVal;
    } 

ก่อนอื่นตรวจสอบว่าคุณอยู่ในกระบวนการ 64 บิตหรือไม่ หากคุณไม่ได้ตรวจสอบว่ากระบวนการ 32 บิตเป็น Wow64Process


13
สิ่งนี้จะล้มเหลวภายใต้ Win2000 และ WinXP SP1 และรุ่นก่อนหน้า คุณต้องตรวจสอบว่ามีฟังก์ชั่น IsWow64Process () อยู่หรือไม่ก่อนที่จะเรียกใช้เพราะมีเฉพาะใน XP SP2 และ Vista / Win7
user9876

2
@ user9876 มีใครบ้างหรือไม่ที่ยังคงกำหนดเป้าหมายระบบโบราณเหล่านั้น
CMircea

5
ตัวอย่างนี้ล้มเหลวในการจัดการอินสแตนซ์กระบวนการที่ส่งคืนโดย Process.GetCurrentProcess ()
Joe

42

Microsoft ได้วางตัวอย่างโค้ดสำหรับสิ่งนี้:

http://1code.codeplex.com/SourceControl/changeset/view/39074#842775

ดูเหมือนว่านี้:

    /// <summary>
    /// The function determines whether the current operating system is a 
    /// 64-bit operating system.
    /// </summary>
    /// <returns>
    /// The function returns true if the operating system is 64-bit; 
    /// otherwise, it returns false.
    /// </returns>
    public static bool Is64BitOperatingSystem()
    {
        if (IntPtr.Size == 8)  // 64-bit programs run only on Win64
        {
            return true;
        }
        else  // 32-bit programs run on both 32-bit and 64-bit Windows
        {
            // Detect whether the current process is a 32-bit process 
            // running on a 64-bit system.
            bool flag;
            return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
                IsWow64Process(GetCurrentProcess(), out flag)) && flag);
        }
    }

    /// <summary>
    /// The function determins whether a method exists in the export 
    /// table of a certain module.
    /// </summary>
    /// <param name="moduleName">The name of the module</param>
    /// <param name="methodName">The name of the method</param>
    /// <returns>
    /// The function returns true if the method specified by methodName 
    /// exists in the export table of the module specified by moduleName.
    /// </returns>
    static bool DoesWin32MethodExist(string moduleName, string methodName)
    {
        IntPtr moduleHandle = GetModuleHandle(moduleName);
        if (moduleHandle == IntPtr.Zero)
        {
            return false;
        }
        return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
    }

    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    static extern IntPtr GetProcAddress(IntPtr hModule,
        [MarshalAs(UnmanagedType.LPStr)]string procName);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

มีรุ่น WMI ให้บริการเช่นกัน (สำหรับการทดสอบเครื่องระยะไกล)


1
หมายเหตุว่ารหัสนี้ได้รับใบอนุญาตภายใต้ใบอนุญาตสาธารณะไมโครซอฟท์
ภาระ

รุ่น WMI ที่ไม่มี. NET ฉันต้องการที่จะเห็นว่ายังไม่พบมัน
JohnZaj

16

นอกจากนี้คุณยังสามารถตรวจสอบPROCESSOR_ARCHITECTUREตัวแปรสภาพแวดล้อม

ไม่มีอยู่หรือตั้งค่าเป็น "x86" บน Windows 32 บิต

private int GetOSArchitecture()
{
    string pa = 
        Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || 
             String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
}

1
เพียงเพราะคุณมีโปรเซสเซอร์ 64 บิตไม่ได้หมายความว่าคุณมีระบบปฏิบัติการ 64 บิต
เดวิด

2
@David นี่รายงานสถาปัตยกรรมโปรเซสเซอร์ของ Windows; ไม่ใช่ซีพียู ดูคำอธิบายโดยละเอียดเริ่มต้นที่ "รหัส" ในหน้านี้: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley

เพียงเพื่อเพิ่ม 2 เซนต์เมื่อคุณทำงานนี้และแอปของคุณถูกกำหนดค่าให้prefer 32-bitกับการAny CPUเป็นของคุณPlatform Targetแล้วคุณจะได้รับx86แต่ถ้าคุณไม่เลือกมันแล้วคุณจะได้รับPrefer 32-bit AMD64
XAMlMAX

14

จากบล็อก Chriz Yuen

C # .Net 4.0 แนะนำสองคุณสมบัติใหม่ของสภาพแวดล้อม Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

โปรดระวังเมื่อคุณใช้คุณสมบัติทั้งสองนี้ ทดสอบเครื่อง Windows 7 64bits

//Workspace: Target Platform x86
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess False

//Workspace: Target Platform x64
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True

//Workspace: Target Platform Any
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True

12

วิธีที่เร็วที่สุด:

if(IntPtr.Size == 8) {
    // 64 bit machine
} else if(IntPtr.Size == 4)  {
    // 32 bit machine
} 

หมายเหตุ:นี่ตรงมากและทำงานอย่างถูกต้องใน 64- บิตเฉพาะในกรณีที่โปรแกรมไม่บังคับให้ดำเนินการเป็นกระบวนการแบบ 32 บิต (เช่นผ่าน<Prefer32Bit>true</Prefer32Bit>ในการตั้งค่าโครงการ)


32
สิ่งนี้จะไม่ทำงาน - หากใช้งานใน. NET Framework 2.0 แบบ 32 บิตบน Windows 64 บิตจะคืนค่าแบบ 32 บิต
Stefan Schultze

ใช่ฉันลืมสถานการณ์นี้ ฉันได้แก้ไขคำถามเพื่อพูดถึงเรื่องนี้เช่นกัน ขอบคุณสเตฟานมก.
Marc

1
สิ่งนี้ไม่ถูกต้อง แพลตฟอร์มอาจเป็น 64 บิต แต่คุณยังคงทำงานในโหมด 32 บิต
เซบาสเตียนกู๊ด

11

ลองสิ่งนี้:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess

5
ขอบคุณสำหรับการป้อนข้อมูลของคุณ แต่โปรดอ่านคำตอบที่มีอยู่ก่อนโพสต์ตามที่ได้รับการแก้ปัญหานี้แล้ว โปรดทราบด้วยว่าคำถามดั้งเดิมนั้นเกี่ยวกับ. net 2 ซึ่งไม่มีคุณสมบัติสองอย่างนี้ซึ่งได้รับการแนะนำให้รู้จักกับ. net 4 เท่านั้น
Marc

9

@foobar: ถูกต้องมันง่ายเกินไป;)

ใน 99% ของกรณีผู้พัฒนาที่มีพื้นหลังผู้ดูแลระบบอ่อนแอในที่สุดก็ไม่ได้ตระหนักถึงพลังที่ Microsoft ได้จัดเตรียมไว้สำหรับทุกคนในการระบุ Windows

ผู้ดูแลระบบจะเขียนโค้ดที่ดีและง่ายกว่าเสมอเมื่อพูดถึงประเด็นดังกล่าว

อย่างไรก็ตามสิ่งหนึ่งที่ควรทราบการสร้างการกำหนดค่าจะต้องเป็นAnyCPUสำหรับตัวแปรสภาพแวดล้อมนี้เพื่อส่งคืนค่าที่ถูกต้องในระบบที่ถูกต้อง:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

สิ่งนี้จะส่งคืน "X86" บน Windows 32 บิตและ "AMD64" บน Windows 64 บิต


4
โซลูชันของคุณจะส่งคืน x86 บน MacBook Pro พร้อมกับ Intel i7-3720QM ไมโครโปรเซสเซอร์ที่ใช้ Bootcamp พร้อมกับพาร์ติชัน Widows 7 Ultimate โซลูชันของ Stefan Schultze ระบุโปรเซสเซอร์อย่างถูกต้องเป็น 64 บิต ฉันแน่ใจว่าโซลูชันของคุณใช้งานได้กับพีซีที่ใช้ Windows 99% +1 สำหรับลอง
Mark Kram

Nope ส่งคืน "x86" บน windows 7 pro ของฉันระบบปฏิบัติการ 64 บิต
Hagai L

7

การใช้dotPeekช่วยในการดูว่าเฟรมเวิร์กทำอย่างไร โดยที่ในใจนี่คือสิ่งที่ฉันเกิดขึ้น:

public static class EnvironmentHelper
{
    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll")]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("kernel32")]
    static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    [DllImport("kernel32.dll")]
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

    public static bool Is64BitOperatingSystem()
    {
        // Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64.
        if (IntPtr.Size == 8)
            return true;
        // Check if this process is an x86 process running on an x64 environment.
        IntPtr moduleHandle = GetModuleHandle("kernel32");
        if (moduleHandle != IntPtr.Zero)
        {
            IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process");
            if (processAddress != IntPtr.Zero)
            {
                bool result;
                if (IsWow64Process(GetCurrentProcess(), out result) && result)
                    return true;
            }
        }
        // The environment must be an x86 environment.
        return false;
    }
}

ตัวอย่างการใช้งาน:

EnvironmentHelper.Is64BitOperatingSystem();

6

ใช้ตัวแปรสภาพแวดล้อมทั้งสองนี้ (รหัสหลอก):

if (PROCESSOR_ARCHITECTURE = x86 &&
    isDefined(PROCESSOR_ARCHITEW6432) &&
    PROCESSOR_ARCHITEW6432 = AMD64) {

    //64 bit OS
}
else
    if (PROCESSOR_ARCHITECTURE = AMD64) {
        //64 bit OS
    }
    else
        if (PROCESSOR_ARCHITECTURE = x86) {
            //32 bit OS
        }

โปรดดูที่โพสต์บล็อกHOWTO: ตรวจหา Bitness


คุณเห็นส่วนที่คำถามเกี่ยวกับ. NET ไม่ใช่ C / C ++ หรือไม่ และนี่คือเวลารวบรวมกับการตรวจสอบรันไทม์ นอกจากนี้รหัสกำลังทำงานที่ได้รับมอบหมายและไม่ได้ทำการเปรียบเทียบ
dvallejo

รหัสนี้ทำงานบน. NET (ทดสอบบน 2.0) ตัวแปร Env สามารถเข้าถึงได้โดย: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ( "PROCESSOR_ARCHITEW6432");
andrew.fox

5

ฉันใช้การตรวจสอบนี้กับความสำเร็จในระบบปฏิบัติการหลายระบบ:

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%windir%\SysWOW64"));
   }
}

โฟลเดอร์นี้มีชื่อว่า "SysWOW64" เสมอไม่ว่าภาษาของระบบปฏิบัติการจะเป็นอะไรก็ตาม สิ่งนี้ใช้ได้สำหรับ. NET Framework 1.1 หรือสูงกว่า


และอะไรทำให้ฉันในฐานะผู้ใช้ที่มีสิทธิ์ระดับผู้ดูแลไม่ให้สร้างโฟลเดอร์ที่เรียกว่าSysWOW64บน%windir%ระบบปฏิบัติการ 32 บิต การมีอยู่ของโฟลเดอร์หมายความว่า: มีโฟลเดอร์อยู่
cogumel0

โอกาสที่ผู้ใช้จะสร้างโฟลเดอร์ดังกล่าวโดยมีวัตถุประสงค์คืออะไร? นี่เป็นวิธีที่แตกต่างกันในการตรวจสอบว่าระบบปฏิบัติการเป็น x64 หรือไม่
Alexandru Dicu

คอมพิวเตอร์ของคุณมีโอกาสติดไวรัสอะไรบ้าง? เนื่องจากโอกาสที่ค่อนข้างต่ำดีกว่าไม่ติดตั้งการป้องกันใด ๆ แล้ว ... การเขียนโปรแกรมไม่เกี่ยวกับการสร้างสิ่งที่มีโอกาสน้อยที่รู้เท่าทันความล้มเหลว มันเกี่ยวกับการสร้างสิ่งที่มีโอกาสน้อยที่จะเกิดความล้มเหลวโดยไม่รู้ตัว - จากนั้นทำการแก้ไข ครั้งแรกเรียกว่าการเขียนโปรแกรมที่ไม่ดี / การใช้งานไม่ดีที่สองเรียกว่าข้อบกพร่อง
cogumel0

@AlexandruDicu คุณควรพูดถึงในคำตอบว่าวิธีการนี้ไม่ถูกต้อง 100% และยังมีความเสี่ยงที่จะให้ผลลัพธ์ที่ไม่ถูกต้องในกรณีที่โฟลเดอร์ถูกสร้างขึ้นตามวัตถุประสงค์โดยแอปหรือผู้ใช้บุคคลที่สามใด ๆ
Rajesh Mishra

4

ฉันต้องทำสิ่งนี้ แต่ฉันต้องสามารถเป็นผู้ดูแลระบบได้จากระยะไกลไม่ว่าในกรณีนี้ดูเหมือนว่าจะทำงานได้ดีสำหรับฉัน:

    public static bool is64bit(String host)
    {
        using (var reg = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host))
        using (var key = reg.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\"))
        {
            return key.GetValue("ProgramFilesDir (x86)") !=null;
        }
    }

4

นี่คือวิธีการแก้ปัญหาตามรหัสไมโครซอฟท์ที่http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 มันใช้วิธีการขยายเพื่อนำมาใช้รหัสได้ง่าย

การใช้งานที่เป็นไปได้บางอย่างแสดงอยู่ด้านล่าง:

bool bIs64BitOS = System.Environment.OSVersion.IsWin64BitOS();

bool bIs64BitProc = System.Diagnostics.Process.GetCurrentProcess().Is64BitProc();

//Hosts the extension methods  
public static class OSHelperTools  
{  
    /// <summary>     
    /// The function determines whether the current operating system is a      
    /// 64-bit operating system.     
    /// </summary>     
    /// <returns>     
    /// The function returns true if the operating system is 64-bit;      
    /// otherwise, it returns false.     
    /// </returns>    
    public static bool IsWin64BitOS(this OperatingSystem os)  
    {  
        if (IntPtr.Size == 8)  
        // 64-bit programs run only on Win64           
            return true;   
        else// 32-bit programs run on both 32-bit and 64-bit Windows     
        {   // Detect whether the current process is a 32-bit process                
            // running on a 64-bit system.               
            return Process.GetCurrentProcess().Is64BitProc();  
        }  
    }  

    /// <summary>  
    /// Checks if the process is 64 bit  
    /// </summary>  
    /// <param name="os"></param>  
    /// <returns>  
    /// The function returns true if the process is 64-bit;        
    /// otherwise, it returns false.  
    /// </returns>    
    public static bool Is64BitProc(this System.Diagnostics.Process p)  
    {  
        // 32-bit programs run on both 32-bit and 64-bit Windows           
        // Detect whether the current process is a 32-bit process                
        // running on a 64-bit system.               
        bool result;  
        return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(p.Handle, out result)) && result);  
    }  

    /// <summary>     
    /// The function determins whether a method exists in the export      
    /// table of a certain module.     
    /// </summary>     
    /// <param name="moduleName">The name of the module</param>     
    /// <param name="methodName">The name of the method</param>     
    /// <returns>     
    /// The function returns true if the method specified by methodName      
    /// exists in the export table of the module specified by moduleName.     
    /// </returns>       
    static bool DoesWin32MethodExist(string moduleName, string methodName)  
    {  
        IntPtr moduleHandle = GetModuleHandle(moduleName);  
        if (moduleHandle == IntPtr.Zero)  
            return false;    
        return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);   
    }  
    [DllImport("kernel32.dll")]  
    static extern IntPtr GetCurrentProcess();  

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    static extern IntPtr GetModuleHandle(string moduleName);  

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]  
    static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName);  

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]  
    [return: MarshalAs(UnmanagedType.Bool)]  
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);  
}

ดูเหมือนว่าลิงค์ CodePlex จะใช้งานไม่ได้
Peter Mortensen

3

นี่คือวิธีการโดยตรงใน C # โดยใช้ DllImport จากหน้านี้

[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; 
} 

คุณยังคงต้องตรวจสอบขนาดของตัวชี้แรกมิฉะนั้นมันเป็นเพียงแค่การตรวจสอบถ้ามันเป็นกระบวนการที่ 32 บิตบนระบบ 64 บิต
บรูโน่โลเปส

1
เกิดปัญหากับระบบปฏิบัติการรุ่นเก่าด้วยเนื่องจากIsWow64Processไม่มีอยู่
พหุนาม

3

ฉันใช้รหัสติดตาม หมายเหตุ: มันถูกสร้างขึ้นสำหรับโครงการ AnyCPU

    public static bool Is32bitProcess(Process proc) {
        if (!IsThis64bitProcess()) return true; // We're in 32-bit mode, so all are 32-bit.

        foreach (ProcessModule module in proc.Modules) {
            try {
                string fname = Path.GetFileName(module.FileName).ToLowerInvariant();
                if (fname.Contains("wow64")) {
                    return true;
                }
            } catch {
                // What on earth is going on here?
            }
        }
        return false;
    }

    public static bool Is64bitProcess(Process proc) {
        return !Is32bitProcess(proc);
    }

    public static bool IsThis64bitProcess() {
        return (IntPtr.Size == 8);
    }

2

ฉันพบสิ่งนี้เป็นวิธีที่ดีที่สุดในการตรวจสอบแพลตฟอร์มของระบบและกระบวนการ:

bool 64BitSystem = Environment.Is64BitOperatingSystem;
bool 64BitProcess = Environment.Is64BitProcess;

คุณสมบัติแรกส่งคืน true สำหรับระบบ 64- บิตและ false สำหรับ 32- บิต คุณสมบัติที่สองส่งคืน true สำหรับกระบวนการ 64- ​​บิตและ false สำหรับ 32- บิต

ความต้องการคุณสมบัติทั้งสองนี้เป็นเพราะคุณสามารถเรียกใช้กระบวนการแบบ 32 บิตบนระบบ 64 บิตดังนั้นคุณจะต้องตรวจสอบทั้งระบบและกระบวนการ


1
ใส่ _ หรือตัวอักษรด้านหน้าชื่อตัวแปรถ้าคุณต้องการให้มันสร้างใน c # (ชื่อตัวแปรไม่เริ่มต้นด้วยตัวเลขใน c # เท่าที่ IDE ของฉันบอกฉัน!)
Chris


2

นี่คือวิธีการของWindows Management Instrumentation (WMI):

string _osVersion = "";
string _osServicePack = "";
string _osArchitecture = "";

ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
ManagementObjectCollection collection = searcher.Get();

foreach (ManagementObject mbo in collection)
{
    _osVersion = mbo.GetPropertyValue("Caption").ToString();
    _osServicePack = string.Format("{0}.{1}", mbo.GetPropertyValue("ServicePackMajorVersion").ToString(), mbo.GetPropertyValue("ServicePackMinorVersion").ToString());

    try
    {
        _osArchitecture = mbo.GetPropertyValue("OSArchitecture").ToString();
    }
    catch
    {
        // OSArchitecture only supported on Windows 7/Windows Server 2008
    }
}

Console.WriteLine("osVersion     : " + _osVersion);
Console.WriteLine("osServicePack : " + _osServicePack);
Console.WriteLine("osArchitecture: " + _osArchitecture);

/////////////////////////////////////////
// Test on Windows 7 64-bit
//
// osVersion     : Microsoft Windows 7 Professional
// osservicePack : 1.0
// osArchitecture: 64-bit

/////////////////////////////////////////
// Test on Windows Server 2008 64-bit
//    --The extra r's come from the registered trademark
//
// osVersion     : Microsoftr Windows Serverr 2008 Standard
// osServicePack : 1.0
// osArchitecture: 64-bit

/////////////////////////////////////////
// Test on Windows Server 2003 32-bit
//    --OSArchitecture property not supported on W2K3
//
// osVersion     : Microsoft(R) Windows(R) Server 2003, Standard Edition
// osServicePack : 2.0
// osArchitecture:

1

OSInfo.Bits

using System;
namespace CSharp411
{
    class Program
    {
        static void Main( string[] args )
        {
           Console.WriteLine( "Operation System Information" );
           Console.WriteLine( "----------------------------" );
           Console.WriteLine( "Name = {0}", OSInfo.Name );
           Console.WriteLine( "Edition = {0}", OSInfo.Edition );
           Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
           Console.WriteLine( "Version = {0}", OSInfo.VersionString );
           Console.WriteLine( "Bits = {0}", OSInfo.Bits );
           Console.ReadLine();
        }
    }
}

3
ทั้งหมดนี้เป็นสิ่งที่ดี แต่คลาสนี้มาจาก Microsoft.UpdateServices.Ad บริหารเนมสเปซซึ่งเป็น Microsoft WSUS ฉันไม่ชอบที่จะรวมการอ้างอิงนี้เพียงแค่รู้บิตของแพลตฟอร์ม
Marc

"C: \ Program Files \ Microsoft.NET \ SDK \ v2.0 64 บิต \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico

1

รวมรหัสต่อไปนี้เป็นคลาสในโครงการของคุณ:

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

    public static int GetBit()
    {
        int MethodResult = "";
        try
        {
            int Architecture = 32;

            if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6)
            {
                using (Process p = Process.GetCurrentProcess())
                {
                    bool Is64Bit;

                    if (IsWow64Process(p.Handle, out Is64Bit))
                    {
                        if (Is64Bit)
                        {
                            Architecture = 64;

                        }

                    }

                }

            }

            MethodResult = Architecture;

        }
        catch //(Exception ex)
        {
            //ex.HandleException();
        }
        return MethodResult;
    }

ใช้มันอย่างนั้น:

string Architecture = "This is a " + GetBit() + "bit machine";

0

ใช้สิ่งนี้เพื่อรับสถาปัตยกรรม Windows ที่ติดตั้ง:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}

ฉันไม่มีคุณสมบัติ ProgramFilesX86 ใน w7x64 vs.net 2010
Christian Casutt เมื่อ

0

ระบุว่าคำตอบที่ยอมรับนั้นซับซ้อนมาก มีวิธีที่ง่ายกว่า Mine เป็นรูปแบบของ anaswer ของ alexandrudicu เมื่อพิจารณาว่า Windows 64 บิตติดตั้งแอปพลิเคชั่น 32 บิตใน Program Files (x86) คุณสามารถตรวจสอบว่ามีโฟลเดอร์นั้นอยู่หรือไม่โดยใช้ตัวแปรสภาพแวดล้อม

เช่น

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES(X86)%"));
   }
}

สำหรับฉันนี้เร็วขึ้นและง่ายขึ้น ระบุว่าฉันยังต้องการเข้าถึงเส้นทางเฉพาะภายใต้โฟลเดอร์นั้นตามเวอร์ชันของระบบปฏิบัติการ


2
คำตอบที่ได้รับการยอมรับสำหรับ NET 2.0 หากคุณใช้. NET 4.0 หรือใหม่กว่าให้ใช้ Environment.Is64BitOperatingSystem ตามที่คุณเห็นในคำตอบด้วยคะแนนโหวตมากที่สุด
Marc

ใช่ฉันมีไว้สำหรับ. net 2.0 ด้วย
John Demetriou

-2

สนุก ;-)

Function Is64Bit() As Boolean

    Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")

End Function

-1 เนื่องจากจะไม่สามารถใช้งานได้กับการติดตั้ง Windows ที่แปล และใช้ VB.net ในขณะที่คำถามถูกแท็กสำหรับ C #
Marc

-3

เพียงแค่ดูว่ามี "C: \ Program Files (x86)" อยู่หรือไม่ ถ้าไม่เช่นนั้นแสดงว่าคุณใช้ระบบปฏิบัติการ 32 บิต ถ้าเป็นเช่นนั้นแสดงว่าระบบปฏิบัติการเป็น 64 บิต (Windows Vista หรือ Windows 7) ดูเหมือนง่ายพอ ...


5
ตรวจสอบให้แน่ใจว่าคุณได้รับชื่อไดเรกทอรีที่แปลเป็นภาษาท้องถิ่นที่ถูกต้องจาก Win32 API แทนที่จะเป็นฮาร์ดโค้ด
Christian Hayter

ฉันจะบอกว่าเป็นความคิดที่ดี แต่คุณไม่สามารถสันนิษฐานได้ว่าผู้ใช้จะไม่ทำสิ่งนี้ด้วยเหตุผลที่คลุมเครือ
GurdeepS

2
แอปพลิเคชั่นที่เขียนไม่ดีบางตัวกำลังติดตั้งโดยตรงกับ "Program Files (x86)" โดยไม่คำนึงถึงสถาปัตยกรรม ฉันมีไดเรกทอรีนั้นในเครื่อง 32- บิตของฉันขอบคุณ SOAPSonar ตัวอย่างเช่น
ภาระ

-4

ฉันใช้:

Dim drivelet As String = Application.StartupPath.ToString
If Directory.Exists(drivelet(0) & ":\Program Files (x86)") Then
    MsgBox("64bit")
Else
    MsgBox("32bit")
End if

นี่จะเป็นเส้นทางที่แอปพลิเคชันของคุณเปิดตัวในกรณีที่คุณติดตั้งในสถานที่ต่าง ๆ บนคอมพิวเตอร์ นอกจากนี้คุณก็สามารถทำทั่วไปC:\เส้นทางตั้งแต่ 99.9% ของคอมพิวเตอร์ออกมีการติดตั้ง Windows C:\ใน


8
วิธีการที่เลวร้ายมาก จะเกิดอะไรขึ้นหากในอนาคตไดเรกทอรีนี้จะถูกเปลี่ยนชื่อ Windows รุ่นแปลเป็นภาษาท้องถิ่นแล้วหรือยัง? ใน Windows XP German "Program Files" เรียกว่า "Program" ฉันไม่แน่ใจ แต่ XP 64 อาจเรียกว่า "โปรแกรม (x86)"
Marc

1
ฉันไม่แนะนำ แต่คุณสามารถแก้ไขปัญหาการโลคัลไลซ์เซชันได้ด้วยการขยาย var โปรแกรมด้านสิ่งแวดล้อม (x86)%
Matthew Lock

-7

ฉันใช้เวอร์ชันต่อไปนี้:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }

6
สิ่งนี้ใช้ไม่ได้กับเวอร์ชั่น XP ที่ไม่ใช่ภาษาอังกฤษ
Daniel Schlößer

แต่ถึงแม้ระบบ 64 บิตมีนี้ฮ่า ๆ โฟลเดอร์
carefulnow1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.