Bagaimana cara mendeteksi platform Windows 64-bit dengan .NET?

269

Dalam aplikasi .NET 2.0 C # saya menggunakan kode berikut untuk mendeteksi platform sistem operasi:

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

Ini mengembalikan "Win32NT". Masalahnya adalah ia mengembalikan "Win32NT" bahkan ketika berjalan pada Windows Vista 64-bit.

Apakah ada metode lain untuk mengetahui platform yang benar (32 atau 64 bit)?

Perhatikan bahwa itu juga harus mendeteksi 64 bit ketika dijalankan sebagai aplikasi 32 bit pada Windows 64 bit.

Marc
sumber

Jawaban:

200

IntPtr.Size tidak akan mengembalikan nilai yang benar jika berjalan dalam 32-bit .NET Framework 2.0 pada Windows 64-bit (ini akan mengembalikan 32-bit).

Seperti yang dijelaskan oleh Raymond Chen dari Microsoft, Anda harus terlebih dahulu memeriksa apakah berjalan dalam proses 64-bit (saya pikir dalam. NET Anda dapat melakukannya dengan memeriksa IntPtr.Size), dan jika Anda menjalankan proses 32-bit, Anda masih harus memanggil fungsi Win API IsWow64Process. Jika ini mengembalikan true, Anda sedang menjalankan proses 32-bit pada Windows 64-bit.

Microsoft Raymond Chen: Cara mendeteksi secara terprogram apakah Anda menjalankan Windows 64-bit

Solusi saya:

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;
    }
}
Stefan Schultze
sumber
7
Ketika berjalan pada OS 32 bit, setiap panggilan ke IsWow64Process akan menimbulkan pengecualian karena entri tersebut tidak ada dari kernel32.dll. Anda harus memeriksa solusi yang ditunjukkan dari codeplex di 1code.codeplex.com/SourceControl/changeset/view/39074#842775. Saya juga memiliki solusi berdasarkan kode yang tercantum di bagian bawah halaman ini, yang menggunakan metode ekstensi jika Anda peduli menggunakan kembali kode.
dmihailescu
7
IsWow64Process diperkenalkan dengan Win XP SP2. Kode ini berfungsi dengan baik jika Anda memerlukan XP SP2 atau versi yang lebih baru.
Marc
3
@dmihailescu, Anda bisa menggunakan DoesWin32MethodExist sebelum memanggil IsWow64Process, yang merupakan implementasi .net 4.0 dari is64BitOperatingSystem.
noobish
4
Solusi Anda mengembalikan nilai yang benar pada MacBook Pro dengan mikroprosesor Intel i7-3720QM yang menjalankan Bootcamp menggunakan partisi Widows 7 Ultimate. +1
Mark Kram
11
FYI: dimulai dengan .Net 4.0 Anda cukup memeriksa System.Environment.Is64BitOperatingSystem. Bisakah Anda mengedit ini menjadi jawaban Anda, atau memberi saya izin untuk mengeditnya menjadi jawaban Anda?
Joel Coehoorn
242

.NET 4 memiliki dua properti baru di kelas Lingkungan, Is64BitProcess dan Is64BitOperatingSystem . Menariknya, jika Anda menggunakan Reflector Anda dapat melihat mereka diimplementasikan secara berbeda dalam versi 32-bit & 64-bit dari mscorlib. Versi 32-bit mengembalikan false untuk Is64BitProcess dan memanggil IsWow64Process melalui P / Invoke untuk Is64BitOperatingSystem. Versi 64-bit hanya mengembalikan true untuk keduanya.

Phil Devaney
sumber
5
Alih-alih Reflektor, mengapa tidak mengunduh sumbernya saja. Kemudian Anda mendapatkan komentar dan "catatan" lainnya.
AMissico
3
Menurut sumber referensi, ia melakukan sesuatu seperti ini: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(pseudo-code)
Polinomial
5
Bagus. Jika pengguna menggunakan .NET 4.0 ini jelas merupakan jawaban yang benar (yaitu Environment.Is64BitOperatingSystem). - Properti FYI tampaknya tidak ada di .NET 3.5.
BrainSlugs83
4
Ini tidak menjawab pertanyaan yang secara khusus mengatakan. Net 2.0
abbottdev
.NET Core telah dirilis di bawah lisensi MIT, yang berarti Anda dapat membaca kode sumber untuk Is64BitProcessdan Is64BitOperatingSystem(tautan untuk versi 2.0).
Cristian Ciupitu
51

Ini hanya implementasi dari apa yang disarankan di atas oleh Bruno Lopez, tetapi bekerja pada Win2k + semua paket layanan WinXP. Baru saja tahu saya akan mempostingnya sehingga orang lain tidak perlu menggulungnya dengan tangan. (akan diposting sebagai komentar, tapi saya pengguna baru!)

[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;
}
yaaa
sumber
49

Jawaban lengkapnya adalah ini (diambil dari jawaban stefan-mg, ripper234 dan 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;
    } 

Pertama periksa apakah Anda sedang dalam proses 64 bit. Jika tidak, periksa apakah proses 32 bit adalah Proses Wow64.

Bruno Lopes
sumber
13
Ini akan gagal di bawah Win2000 dan WinXP SP1 dan sebelumnya. Anda perlu memeriksa apakah fungsi IsWow64Process () ada sebelum Anda menyebutnya, karena itu hanya diperkenalkan di XP SP2 dan Vista / Win7.
user9876
2
@ user9876, apakah (atau apakah) ada yang masih menargetkan sistem antik itu?
CMircea
5
Sampel ini gagal untuk membuang instance Proses dikembalikan oleh Process.GetCurrentProcess ().
Joe
42

Microsoft telah menempatkan contoh kode untuk ini:

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

Ini terlihat seperti ini:

    /// <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);

Ada versi WMI juga tersedia (untuk menguji mesin jarak jauh).

synhershko
sumber
1
Perhatikan bahwa kode ini dilisensikan di bawah Lisensi Publik Microsoft .
ladenedge
Versi WMI tanpa .net yang dikelola? Saya ingin melihat itu, belum menemukannya sejauh ini
JohnZaj
16

Anda juga dapat memeriksa PROCESSOR_ARCHITECTUREvariabel lingkungan.

Entah itu tidak ada atau diatur ke "x86" pada Windows 32-bit.

private int GetOSArchitecture()
{
    string pa = 
        Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || 
             String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
}
Andrew Ensley
sumber
1
Hanya karena Anda memiliki prosesor 64 bit tidak berarti Anda memiliki os 64 bit
David
2
@ David Ini melaporkan arsitektur prosesor Windows; bukan CPU. Lihat penjelasan terperinci mulai dari "Kode" di halaman ini: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley
Hanya untuk menambah 2 sen, ketika Anda menjalankan ini, dan aplikasi Anda dikonfigurasi untuk prefer 32-bitdengan Any CPUsebagai Anda Platform Targetmaka Anda akan mendapatkan x86, tetapi jika Anda untick Prefer 32-bititu Anda kemudian akan mendapatkan AMD64.
XAMlMAX
14

Dari blog Chriz Yuen

C # .Net 4.0 Memperkenalkan dua lingkungan properti properti baru Environment.Is64BitOperatingSystem; Lingkungan.Is64Bit Proses;

Harap berhati-hati saat Anda menggunakan kedua properti ini. Tes pada Windows 7 64bits Machine

//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
listrikbah
sumber
12

Cara tercepat:

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

Catatan: ini sangat langsung dan bekerja dengan benar pada 64-bit hanya jika program tidak memaksa eksekusi sebagai proses 32-bit (misalnya melalui<Prefer32Bit>true</Prefer32Bit>dalam pengaturan proyek).

BobbyShaftoe
sumber
32
Ini tidak akan berfungsi - jika berjalan dalam .NET Framework 2.0 32-bit pada Windows 64-bit, itu akan mengembalikan 32-bit.
Stefan Schultze
Benar saya lupa situasi ini. Saya telah mengedit pertanyaan untuk menyebutkan ini juga. Terima kasih Stefan-mg.
Marc
1
Ini tidak benar; platform mungkin 64 bit tetapi Anda masih berjalan dalam mode 32-bit.
Sebastian Good
11

Coba ini:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
pengguna2235582
sumber
5
Terima kasih atas masukan Anda, tetapi harap baca jawaban yang tersedia sebelum memposting karena solusi ini sudah diberikan. Perhatikan juga bahwa pertanyaan awal adalah tentang .net 2 yang tidak memiliki dua properti yang hanya diperkenalkan dengan .net 4.
Marc
9

@foobar: Anda benar, itu terlalu mudah;)

Dalam 99% kasus, pengembang dengan latar belakang administrator sistem yang lemah pada akhirnya gagal untuk menyadari kekuatan yang selalu disediakan Microsoft bagi siapa saja untuk menyebutkan Windows.

Administrator sistem akan selalu menulis kode yang lebih baik dan lebih sederhana ketika sampai pada titik seperti itu.

Namun demikian, satu hal yang perlu diperhatikan, konfigurasi build harus AnyCPU untuk variabel lingkungan ini untuk mengembalikan nilai yang benar pada sistem yang benar:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Ini akan mengembalikan "X86" pada Windows 32-bit, dan "AMD64" pada Windows 64-bit.

SomeSysadmin
sumber
4
Solusi Anda mengembalikan x86 pada MacBook Pro dengan mikroprosesor Intel i7-3720QM yang menjalankan Bootcamp dengan partisi Widows 7 Ultimate. Solusi Stefan Schultze dengan benar Mengidentifikasi prosesor sebagai 64 bit. Saya yakin bahwa solusi Anda berfungsi pada 99% dari PC berbasis Windows di luar sana. +1 untuk dicoba.
Mark Kram
Nggak. mengembalikan "x86" di windows 7 pro, Sistem Operasi 64-bit.
Hagai L
7

Menggunakan dotPeek membantu untuk melihat bagaimana kerangka kerja sebenarnya melakukannya. Dengan mengingat hal itu, inilah yang saya pikirkan:

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

Contoh penggunaan:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
sumber
6

Gunakan dua variabel lingkungan ini (kode semu):

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
        }

Lihat posting blog HOWTO: Deteksi Proses Bitness .

Santhosh
sumber
Apakah Anda melihat bagian di mana pertanyaannya adalah tentang .NET dan bukan C / C ++? Dan ini adalah waktu kompilasi versus pemeriksaan runtime. Juga, kode melakukan penugasan dan bukan perbandingan.
dvallejo
Kode ini berfungsi pada .NET (diuji pada 2.0). Variabel env dapat diakses oleh: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432");
andrew.fox
5

Saya menggunakan pemeriksaan ini dengan sukses di banyak sistem operasi:

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

Folder ini selalu dinamai "SysWOW64", tidak masalah bahasa sistem operasi. Ini berfungsi untuk .NET Framework 1.1 atau lebih tinggi.

Alexandru Dicu
sumber
Dan apa yang mencegah saya sebagai pengguna dengan hak administratif membuat folder yang disebut SysWOW64pada %windir%OS 32 bit? Kehadiran folder artinya persis seperti itu: bahwa folder itu ada.
cogumel0
Bagaimana kemungkinan seorang pengguna akan membuat folder seperti itu dengan sengaja? Ini hanya cara yang berbeda untuk memeriksa apakah sistem operasi x64.
Alexandru Dicu
Bagaimana kemungkinan komputer Anda terkena virus? Karena kemungkinannya sangat rendah, lebih baik tidak menginstal perlindungan apa pun daripada itu ... Pemrograman bukan tentang menciptakan sesuatu yang memiliki peluang rendah untuk secara sadar gagal. Ini tentang menciptakan sesuatu yang memiliki peluang rendah untuk gagal secara tidak sadar - dan kemudian memperbaikinya. Yang pertama disebut pemrograman buruk / implementasi buruk, yang kedua disebut bug.
cogumel0
@AlexandruDicu Anda harus menyebutkan dalam jawaban bahwa pendekatan ini tidak 100% akurat dan masih berisiko memberikan output yang salah jika folder dibuat dengan sengaja oleh aplikasi pihak ketiga atau pengguna secara manual.
Rajesh Mishra
4

Saya perlu melakukan ini, tetapi saya juga harus dapat sebagai admin melakukannya dari jarak jauh, kedua kasus ini tampaknya bekerja dengan baik untuk saya:

    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;
        }
    }
Julian Hall
sumber
4

Ini adalah solusi berdasarkan kode Microsoft di http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Ini menggunakan metode ekstensi untuk menggunakan kembali kode mudah.

Beberapa kemungkinan penggunaan ditunjukkan di bawah ini:

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);  
}
dmihailescu
sumber
Tautan CodePlex tampaknya rusak.
Peter Mortensen
3

Berikut adalah pendekatan langsung dalam C # menggunakan DllImport dari halaman ini .

[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; 
} 
ripper234
sumber
Anda masih perlu memeriksa ukuran pointer terlebih dahulu, jika tidak hanya memeriksa apakah itu proses 32 bit pada sistem 64 bit
Bruno Lopes
1
Juga macet di OS yang lebih lama, karena IsWow64Processtidak ada.
Polinomial
3

Saya menggunakan kode followin. Catatan: Ini dibuat untuk proyek 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);
    }
Blez
sumber
2

Saya menemukan ini sebagai cara terbaik untuk memeriksa platform sistem dan prosesnya:

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

Properti pertama mengembalikan true untuk sistem 64-bit, dan false untuk 32-bit. Properti kedua mengembalikan true untuk proses 64-bit, dan false untuk 32-bit.

Kebutuhan kedua properti ini adalah karena Anda dapat menjalankan proses 32-bit pada sistem 64-bit, jadi Anda perlu memeriksa sistem dan prosesnya.

OmarElsherif
sumber
1
letakkan _ atau huruf di depan nama variabel jika Anda ingin membuatnya dalam c # (nama variabel jangan mulai dengan angka dalam c # sejauh ide saya mengatakan kepada saya!)
Chris
2

Semua baik-baik saja, tetapi ini juga harus bekerja dari env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Terlalu mudah, mungkin ;-)

Peter Mortensen
sumber
2

Berikut ini adalah pendekatan Instrumentasi Manajemen Windows (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:
pengguna1054695
sumber
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();
        }
    }
}
Greg
sumber
3
Itu semua bagus, tetapi kelas ini dari Microsoft.UpdateServices.Administration namespace yaitu Microsoft WSUS. Saya tidak suka memasukkan referensi ini hanya untuk mengetahui bit platform.
Marc
"C: \ Program Files \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico
1

Sertakan kode berikut ke dalam kelas di proyek Anda:

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

Gunakan seperti ini:

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

Gunakan ini untuk mendapatkan arsitektur Windows yang diinstal:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
pengguna885959
sumber
saya tidak punya properti ProgramFilesX86 di w7x64 vs.net 2010
Christian Casutt
0

Mengingat bahwa jawaban yang diterima sangat kompleks. Ada cara yang lebih sederhana. Milik saya adalah variasi dari jawaban alexandrudicu. Mengingat bahwa windows 64-bit menginstal aplikasi 32-bit dalam Program Files (x86) Anda dapat memeriksa apakah folder itu ada, menggunakan variabel lingkungan (untuk menebus pelokalan yang berbeda)

misalnya

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

Bagi saya ini lebih cepat dan sederhana. Mengingat bahwa saya juga ingin mengakses jalur tertentu di bawah folder itu berdasarkan versi OS.

John Demetriou
sumber
2
Jawaban yang diterima adalah untuk .NET 2.0. Jika Anda menggunakan .NET 4.0 atau yang lebih baru, cukup gunakan Environment.Is64BitOperatingSystem karena Anda dapat menemukan jawaban dengan suara terbanyak.
Marc
Ya, milik saya juga untuk .net 2.0.
John Demetriou
-2

Nikmati ;-)

Function Is64Bit() As Boolean

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

End Function
Majid95
sumber
-1 karena ini tidak akan berfungsi pada instalasi Windows lokal. Dan itu menggunakan VB.net sedangkan pertanyaannya ditandai untuk C #.
Marc
-3

Lihat saja apakah "C: \ Program Files (x86)" ada. Jika tidak, berarti Anda menggunakan OS 32 bit. Jika ya, maka OS-nya 64 bit (Windows Vista atau Windows 7). Tampaknya cukup sederhana ...

John
sumber
5
Pastikan Anda mengambil nama direktori yang dilokalkan dengan benar dari Win32 API alih-alih hardcoding.
Christian Hayter
Saya akan mengatakan itu ide yang bagus, tetapi Anda tidak bisa berasumsi pengguna tidak akan pernah melakukan ini karena alasan yang tidak jelas.
GurdeepS
2
Beberapa aplikasi yang ditulis dengan buruk sekarang menginstal langsung ke "Program Files (x86)" tanpa memperhatikan arsitektur. Saya memiliki direktori itu di mesin 32-bit saya berkat SOAPSonar, misalnya.
ladenedge
-4

Saya menggunakan:

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

Ini mendapatkan jalur di mana aplikasi Anda diluncurkan jika Anda menginstalnya di berbagai tempat di komputer. Juga, Anda bisa melakukan C:\jalur umum karena 99,9% komputer di luar sana telah menginstal Windows C:\.

Ben G
sumber
8
Pendekatan yang sangat buruk. Bagaimana jika di masa depan direktori ini akan diganti namanya? Bagaimana dengan versi lokal Windows? Di Windows XP Jerman "Program Files" disebut "Program". Saya tidak yakin tetapi XP 64 dengan demikian dapat menyebutnya "Program (x86)".
Marc
1
Saya tidak merekomendasikannya tetapi Anda dapat mengatasi masalah lokalisasi dengan memperluas var lingkungan% ProgramFiles (x86)%
Matthew Lock
-7

Saya menggunakan versi berikut ini:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
Josh
sumber
6
Ini tidak berfungsi pada versi XP non-Inggris karena nama Folder Program terlokalisasi.
Daniel Schlößer
Tetapi bahkan sistem 64-bit memiliki folder ini haha
carefulnow1