Jak wykryć 64-bitową platformę Windows za pomocą .NET?

268

W aplikacji .NET 2.0 C # używam następującego kodu do wykrycia platformy systemu operacyjnego:

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

Zwraca „Win32NT”. Problem polega na tym, że zwraca „Win32NT”, nawet jeśli jest uruchomiony w systemie Windows Vista 64-bit.

Czy jest jakaś inna metoda poznania właściwej platformy (32- lub 64-bitowej)?

Należy pamiętać, że powinien również wykrywać 64-bitowe, gdy jest uruchamiany jako aplikacja 32-bitowa w 64-bitowym systemie Windows.

Marc
źródło

Odpowiedzi:

200

IntPtr.Size nie zwróci poprawnej wartości, jeśli działa w 32-bitowym .NET Framework 2.0 w 64-bitowym systemie Windows (zwróci 32-bit).

Jak opisuje Raymond Chen Microsoftu, musisz najpierw sprawdzić, czy działa w procesie 64-bitowym (myślę, że w .NET możesz to zrobić, sprawdzając IntPtr.Size), a jeśli pracujesz w procesie 32-bitowym, nadal wywołać funkcję Win API IsWow64Process. Jeśli zwraca wartość true, uruchomiony jest proces 32-bitowy w 64-bitowym systemie Windows.

Microsoft Raymond Chen: Jak programowo wykryć, czy używasz 64-bitowego systemu Windows

Moje rozwiązanie:

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
źródło
7
W przypadku 32-bitowego systemu operacyjnego każde wywołanie IsWow64Process spowoduje zgłoszenie wyjątku, ponieważ w kernel32.dll brakuje tego wpisu. Powinieneś sprawdzić rozwiązanie pokazane z codeplex na 1code.codeplex.com/SourceControl/changeset/view/39074#842775. Mam również rozwiązanie oparte na tym kodzie wymienionym na dole tej strony, który używa metod rozszerzenia, jeśli zależy ci na ponowne użycie kodu.
dmihailescu
7
IsWow64Process został wprowadzony wraz z Win XP SP2. Ten kod działa poprawnie, jeśli potrzebujesz XP SP2 lub dowolnej nowszej wersji.
Marc
3
@dmihailescu, możesz po prostu Używać DoesWin32MethodExist przed wywołaniem IsWow64Process, co właśnie robi implementacja isnetBitOperatingSystem .NET 4.0.
noobish
4
Twoje rozwiązanie zwraca poprawną wartość na MacBooku Pro z mikroprocesorem Intel i7-3720QM z systemem Bootcamp za pomocą partycji Widows 7 Ultimate. +1
Mark Kram
11
Do Twojej wiadomości: zaczynając od .Net 4.0 możesz po prostu sprawdzić System.Environment.Is64BitOperatingSystem. Czy możesz to zmienić w swojej odpowiedzi lub wyrazić zgodę na edytowanie tego w swojej odpowiedzi?
Joel Coehoorn
241

.NET 4 ma dwie nowe właściwości w klasie Environment: Is64BitProcess i Is64BitOperatingSystem . Co ciekawe, jeśli używasz Reflectora, możesz zobaczyć, że są one zaimplementowane inaczej w 32-bitowych i 64-bitowych wersjach mscorlib. Wersja 32-bitowa zwraca wartość false dla Is64BitProcess i wywołuje IsWow64Process przez P / Invoke dla Is64BitOperatingSystem. Wersja 64-bitowa po prostu zwraca wartość true dla obu.

Phil Devaney
źródło
5
Zamiast Reflector, dlaczego po prostu nie pobrać źródła. Następnie otrzymujesz komentarze i inne „notatki”.
AMissico,
3
Według źródła referencyjnego robi to if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());
Wielomian
5
Miły. Jeśli użytkownik korzysta z .NET 4.0, jest to zdecydowanie poprawna odpowiedź (tj. Environment.Is64BitOperatingSystem). - Właściwość FYI nie pojawia się w .NET 3.5.
BrainSlugs83
4
To nie odpowiada na pytanie, które konkretnie mówi .Net 2.0
abbottdev
.NET Core został wydany na licencji MIT, co oznacza, że ​​możesz odczytać kod źródłowy dla Is64BitProcessi Is64BitOperatingSystem(linki do wersji 2.0).
Cristian Ciupitu
51

To tylko implementacja tego, co sugeruje powyżej Bruno Lopez, ale działa na Win2k + wszystkie dodatki Service Pack dla WinXP. Po prostu pomyślałem, że opublikuję to, aby inni ludzie nie rzucili go ręcznie. (opublikowałby jako komentarz, ale jestem nowym użytkownikiem!)

[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;
}
dwhiteho
źródło
49

Pełna odpowiedź jest następująca (wzięta zarówno z odpowiedzi stefan-mg, ripper234, jak i 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;
    } 

Najpierw sprawdź, czy jesteś w trakcie procesu 64-bitowego. Jeśli nie, sprawdź, czy 32-bitowy proces jest procesem Wow64.

Bruno Lopes
źródło
13
To się nie powiedzie w Win2000 i WinXP SP1 i wcześniejszych. Przed wywołaniem należy sprawdzić, czy funkcja IsWow64Process () istnieje, ponieważ została wprowadzona tylko w XP SP2 i Vista / Win7.
user9876,
2
@ user9876, czy (lub czy) ktoś nadal atakuje te zabytkowe systemy?
CMircea,
5
W tym przykładzie nie można usunąć instancji Process zwróconej przez Process.GetCurrentProcess ().
Joe
42

Microsoft umieścił dla tego przykładowy kod:

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

To wygląda tak:

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

Dostępna jest również wersja WMI (do testowania zdalnych maszyn).

synhershko
źródło
1
Pamiętaj, że ten kod jest objęty licencją Microsoft Public License .
ladenedge
Wersja WMI bez zarządzanego .net? Chciałbym to zobaczyć, jak dotąd nie znalazłem
JohnZaj,
16

Możesz także sprawdzić PROCESSOR_ARCHITECTUREzmienną środowiskową.

Nie istnieje lub jest ustawiony na „x86” w 32-bitowym systemie Windows.

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
źródło
1
To, że masz 64-bitowy procesor, nie oznacza, że ​​masz 64-bitowy system operacyjny
David
2
@David Zgłasza architekturę procesora systemu Windows; nie procesor. Zobacz szczegółowe wyjaśnienie od „Kodeksu” na tej stronie: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley
Wystarczy dodać 2 centów, po uruchomieniu tego, a aplikacja jest skonfigurowany tak, aby prefer 32-bitz Any CPUjak twoje Platform Targetnastępnie dostaniesz x86, ale jeśli odznacz Prefer 32-bitgo będzie wtedy dostać AMD64.
XAMlMAX,
14

Z bloga Chriz Yuen

C # .Net 4.0 Wprowadzono dwie nowe właściwości środowiska Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Zachowaj ostrożność podczas korzystania z obu tych właściwości. Przetestuj na komputerze z systemem Windows 7 64 bity

//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
electricbah
źródło
12

Najszybszy sposób:

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

Uwaga: jest to bardzo bezpośrednie i działa poprawnie na 64-bitach tylko wtedy, gdy program nie wymusza wykonywania jako proces 32-bitowy (np.<Prefer32Bit>true</Prefer32Bit>W ustawieniach projektu).

BobbyShaftoe
źródło
32
To nie zadziała - jeśli działa w 32-bitowym .NET Framework 2.0 w 64-bitowym systemie Windows, zwróci 32-bit.
Stefan Schultze,
Racja, zapomniałem o tej sytuacji. Zredagowałem pytanie, aby o tym wspomnieć. Dzięki, Stefan.
Marc
1
To nie jest poprawne; platforma może mieć 64 bity, ale nadal pracujesz w trybie 32-bitowym.
Sebastian Dobry,
11

Spróbuj tego:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
użytkownik2235582
źródło
5
Dziękujemy za wkład, ale proszę przeczytać dostępne odpowiedzi przed opublikowaniem, ponieważ to rozwiązanie jest już podane. Zauważ też, że pierwotne pytanie dotyczyło .net 2, który nie ma tych dwóch właściwości, które zostały wprowadzone tylko z .net 4.
Marc
9

@foobar: Masz rację, to jest zbyt łatwe;)

W 99% przypadków programiści ze słabym doświadczeniem administratora systemu ostatecznie nie zdają sobie sprawy z mocy, jaką Microsoft zawsze zapewniał każdemu, by wyliczyć Windows.

Administratorzy systemu zawsze piszą lepszy i prostszy kod, jeśli do tego dojdzie.

Niemniej jednak należy zauważyć, że konfiguracja kompilacji musi być AnyCPU, aby ta zmienna środowiskowa zwróciła prawidłowe wartości we właściwych systemach:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Zwróci to „X86” w 32-bitowym systemie Windows i „AMD64” w 64-bitowym systemie Windows.

SomeSysadmin
źródło
4
Twoje rozwiązanie zwraca x86 na MacBooku Pro z mikroprocesorem Intel i7-3720QM z systemem Bootcamp z partycją Widows 7 Ultimate. Rozwiązanie Stefana Schultze poprawnie zidentyfikowało procesor jako 64-bitowy. Jestem pewien, że twoje rozwiązanie działa na 99% komputerów z systemem Windows. +1 za próbę.
Mark Kram,
Nie. zwrócił „x86” w moim 64-bitowym systemie operacyjnym Windows 7 pro.
Hagai L
7

Korzystanie z dotPeek pomaga zobaczyć, jak naprawdę robi to framework. Mając to na uwadze, oto co wymyśliłem:

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

Przykładowe użycie:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
źródło
6

Użyj tych dwóch zmiennych środowiskowych (pseudo-kod):

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
        }

Zobacz post na blogu HOWTO: Detect Bitity .

Santhosh
źródło
Widziałeś część, w której pytanie dotyczyło platformy .NET, a nie C / C ++? I że jest to czas kompilacji w porównaniu do sprawdzenia środowiska wykonawczego. Ponadto kod wykonuje przypisanie, a nie porównania.
dvallejo
Ten kod działa na platformie .NET (testowany na wersji 2.0). Do zmiennych env można uzyskać: Environment.GetEnvironmentVariable („PROCESSOR_ARCHITECTURE”); Environment.GetEnvironmentVariable („PROCESSOR_ARCHITEW6432”);
andrew.fox
5

Z powodzeniem wykorzystałem tę kontrolę w wielu systemach operacyjnych:

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

Ten folder ma zawsze nazwę „SysWOW64”, bez względu na język systemu operacyjnego. Działa to dla .NET Framework 1.1 lub nowszego.

Alexandru Dicu
źródło
A co uniemożliwia mi, jako użytkownikowi z uprawnieniami administracyjnymi, utworzenie folderu wywoływanego SysWOW64w %windir%32-bitowym systemie operacyjnym? Obecność folderu oznacza dokładnie to: że folder jest obecny.
cogumel0
Jakie są szanse, że użytkownik celowo utworzy taki folder? To tylko inny sposób sprawdzenia, czy system operacyjny to x64.
Alexandru Dicu,
Jakie są szanse, że Twój komputer dostanie wirusa? Ponieważ szanse są dość niskie, lepiej nie instalować żadnej ochrony, to ... Programowanie nie polega na stworzeniu czegoś, co ma małe szanse na świadome niepowodzenie. Chodzi o stworzenie czegoś, co ma małe szanse na nieświadomą porażkę - a następnie naprawienie tego. Pierwszy nazywa się złe programowanie / złe wdrożenie, drugi nazywa się błędem.
cogumel0
@AlexandruDicu W odpowiedzi należy wspomnieć, że takie podejście nie jest w 100% dokładne i nadal istnieje ryzyko podania nieprawidłowych danych wyjściowych w przypadku, gdy folder zostanie utworzony celowo przez dowolną aplikację lub użytkownika strony trzeciej.
Rajesh Mishra
4

Muszę to zrobić, ale muszę też być w stanie, jako administrator, robić to zdalnie, w każdym razie wydaje mi się, że działa to całkiem nieźle:

    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
źródło
4

Jest to rozwiązanie oparte na kodzie Microsoft pod adresem http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Wykorzystuje metody rozszerzenia do łatwego ponownego wykorzystania kodu.

Niektóre możliwe zastosowania pokazano poniżej:

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
źródło
Łącze CodePlex wydaje się być zepsute.
Peter Mortensen
3

Oto bezpośrednie podejście w C # przy użyciu DllImport z tej strony .

[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
źródło
Nadal musisz najpierw sprawdzić rozmiar wskaźnika, w przeciwnym razie po prostu sprawdza, czy jest to proces 32-bitowy w systemie 64-bitowym
Bruno Lopes,
1
Zawiesza się również na starszym systemie operacyjnym, ponieważ IsWow64Processnie istnieje.
Wielomian
3

Używam następującego kodu. Uwaga: jest przeznaczony dla projektu 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
źródło
2

Uważam, że jest to najlepszy sposób na sprawdzenie platformy systemu i procesu:

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

Pierwsza właściwość zwraca true dla systemu 64-bitowego, a false dla 32-bitowego. Druga właściwość zwraca true dla procesu 64-bitowego i false dla 32-bitowego.

Potrzeba tych dwóch właściwości polega na tym, że można uruchamiać procesy 32-bitowe w systemie 64-bitowym, dlatego należy sprawdzić zarówno system, jak i proces.

OmarElsherif
źródło
1
umieść _ lub literę przed nazwą zmiennej, jeśli chcesz, aby wbudowała się w c # (nazwy zmiennych nie zaczynają się od liczb w c #, o ile mówi mi mój pomysł!)
Chris
2

Wszystko w porządku, ale powinno to również działać z env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Może zbyt łatwe ;-)

Peter Mortensen
źródło
2

Oto podejście do Instrumentacji zarządzania 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:
użytkownik1054695
źródło
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
źródło
3
To wszystko miłe, ale ta klasa pochodzi z przestrzeni nazw Microsoft.UpdateServices.Administration, którą jest Microsoft WSUS. Nie chcę dołączać tego odniesienia, aby poznać bity platformy.
Marc
"C: Program Files \ \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico
1

Dodaj następujący kod do klasy w swoim projekcie:

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

Używaj go w ten sposób:

string Architecture = "This is a " + GetBit() + "bit machine";
WonderWorker
źródło
0

Użyj tego, aby uzyskać zainstalowaną architekturę Windows:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
użytkownik885959
źródło
nie mam właściwości ProgramFilesX86 na w7x64 vs.net 2010
Christian Casutt
0

Biorąc pod uwagę, że przyjęta odpowiedź jest bardzo złożona. Istnieją prostsze sposoby. Mój jest odmianą anaswer Aleksandra. Biorąc pod uwagę, że 64-bitowe okna instalują 32-bitowe aplikacje w Program Files (x86), możesz sprawdzić, czy ten folder istnieje, używając zmiennych środowiskowych (w celu uzupełnienia różnych lokalizacji)

na przykład

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

To dla mnie jest szybsze i prostsze. Biorąc pod uwagę, że chcę uzyskać dostęp do określonej ścieżki w tym folderze w zależności od wersji systemu operacyjnego.

John Demetriou
źródło
2
Przyjęto odpowiedź na .NET 2.0. Jeśli korzystasz z platformy .NET 4.0 lub nowszej, po prostu użyj środowiska Environment.Is64BitOperatingSystem, tak jak można znaleźć w odpowiedzi na większość głosów.
Marc
Tak, mój jest również dla .net 2.0.
John Demetriou,
-2

Cieszyć się ;-)

Function Is64Bit() As Boolean

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

End Function
Majid95
źródło
-1, ponieważ nie będzie działać w zlokalizowanych instalacjach Windows. I używa VB.net, podczas gdy pytanie jest oznaczone jako C #.
Marc
-3

Zobacz, czy istnieje „C: \ Program Files (x86)”. Jeśli nie, to masz 32-bitowy system operacyjny. Jeśli tak, to system operacyjny jest 64-bitowy (Windows Vista lub Windows 7). Wydaje się to dość proste ...

Jan
źródło
5
Upewnij się, że pobierasz poprawną zlokalizowaną nazwę katalogu z API Win32 zamiast na stałe kodować.
Christian Hayter
Powiedziałbym, że to dobry pomysł, ale nie możesz założyć, że użytkownik nigdy by tego nie zrobił z jakiegoś niejasnego powodu.
GurdeepS
2
Niektóre źle napisane aplikacje instalują się teraz bezpośrednio w „Program Files (x86)” bez względu na architekturę. Mam ten katalog na mojej 32-bitowej maszynie, na przykład dzięki SOAPSonar.
ladenedge
-4

Używam:

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

Uzyskuje to ścieżkę do uruchomienia aplikacji na wypadek, gdybyś zainstalował ją w różnych miejscach na komputerze. Możesz także zrobić ogólną C:\ścieżkę, ponieważ 99,9% komputerów ma zainstalowany system Windows C:\.

Ben G.
źródło
8
Bardzo złe podejście. Co jeśli w przyszłości nazwa tego katalogu zostanie zmieniona? Co ze zlokalizowaną wersją systemu Windows? W systemie Windows XP niemiecki „Program Files” nosi nazwę „Program”. Nie jestem pewien, ale XP 64 może więc nazwać to „Programem (x86)”.
Marc
1
Nie polecam tego, ale można obejść problem z lokalizacją, rozszerzając zmienną środowiskową% ProgramFiles (x86)%
Matthew Lock
-7

Używam wersji:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
Josh
źródło
6
Nie działa to w wersjach XP w języku innym niż angielski z powodu zlokalizowanej nazwy folderów programów.
Daniel Schlößer,
Ale nawet systemy 64-bitowe mają ten folder haha
ostrożny1