Wie erkenne ich eine Windows 64-Bit-Plattform mit .NET?

267

In einer .NET 2.0 C # -Anwendung verwende ich den folgenden Code, um die Betriebssystemplattform zu erkennen:

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

Dies gibt "Win32NT" zurück. Das Problem ist, dass "Win32NT" auch unter Windows Vista 64-Bit zurückgegeben wird.

Gibt es eine andere Methode, um die richtige Plattform zu kennen (32 oder 64 Bit)?

Beachten Sie, dass es auch 64-Bit erkennen sollte, wenn es als 32-Bit-Anwendung unter Windows 64-Bit ausgeführt wird.

Marc
quelle

Antworten:

199

IntPtr.Size gibt nicht den richtigen Wert zurück, wenn es in 32-Bit-.NET Framework 2.0 unter 64-Bit-Windows ausgeführt wird (es würde 32-Bit zurückgeben).

Wie Raymond Chen von Microsoft beschreibt, müssen Sie zuerst prüfen, ob ein 64-Bit-Prozess ausgeführt wird (ich denke, in .NET können Sie dies durch Überprüfen von IntPtr.Size tun), und wenn Sie in einem 32-Bit-Prozess ausgeführt werden, müssen Sie dies immer noch tun müssen die Win-API-Funktion IsWow64Process aufrufen. Wenn dies true zurückgibt, werden Sie in einem 32-Bit-Prozess unter 64-Bit-Windows ausgeführt.

Raymond Chen von Microsoft: So erkennen Sie programmgesteuert, ob Sie unter 64-Bit-Windows ausgeführt werden

Meine Lösung:

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
quelle
7
Bei einem 32-Bit-Betriebssystem löst jeder Aufruf von IsWow64Process eine Ausnahme aus, da dieser Eintrag in kernel32.dll fehlt. Sie sollten die von codeplex unter 1code.codeplex.com/SourceControl/changeset/view/39074#842775 gezeigte Lösung überprüfen. Ich habe auch eine Lösung, die auf dem unten auf dieser Seite aufgeführten Code basiert und bei Bedarf Erweiterungsmethoden verwendet Wiederverwendung des Codes.
Dmihailescu
7
IsWow64Process wurde mit Win XP SP2 eingeführt. Dieser Code funktioniert einwandfrei, wenn Sie XP SP2 oder eine neuere Version benötigen.
Marc
3
@dmihailescu, Sie können DoesWin32MethodExist einfach verwenden, bevor Sie IsWow64Process aufrufen. Dies ist die Aufgabe der .net 4.0-Implementierung von is64BitOperatingSystem.
Noobish
4
Ihre Lösung gibt auf einem MacBook Pro mit Intel i7-3720QM-Mikroprozessor, auf dem Bootcamp mit einer Widows 7 Ultimate-Partition ausgeführt wird, den korrekten Wert zurück. +1
Mark Kram
11
Zu Ihrer Information: Ab .NET 4.0 können Sie dies einfach überprüfen System.Environment.Is64BitOperatingSystem. Können Sie dies in Ihrer Antwort bearbeiten oder mir die Erlaubnis geben, es in Ihrer Antwort zu bearbeiten?
Joel Coehoorn
241

.NET 4 verfügt über zwei neue Eigenschaften in der Umgebungsklasse, Is64BitProcess und Is64BitOperatingSystem . Interessanterweise können Sie bei Verwendung von Reflector feststellen, dass diese in den 32-Bit- und 64-Bit-Versionen von mscorlib unterschiedlich implementiert sind. Die 32-Bit-Version gibt false für Is64BitProcess zurück und ruft IsWow64Process über P / Invoke für Is64BitOperatingSystem auf. Die 64-Bit-Version gibt für beide nur true zurück.

Phil Devaney
quelle
5
Laden Sie statt Reflector einfach die Quelle herunter. Dann erhalten Sie die Kommentare und andere "Notizen".
AMissico
3
Laut der Referenzquelle macht es ungefähr so: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(Pseudocode)
Polynom
5
Nett. Wenn der Benutzer .NET 4.0 verwendet, ist dies definitiv die richtige Antwort (dh Environment.Is64BitOperatingSystem). - Die FYI-Eigenschaft scheint in .NET 3.5 nicht vorhanden zu sein.
BrainSlugs83
4
Dies beantwortet nicht die Frage, die speziell sagt .Net 2.0
Abbottdev
.NET Core wurde unter der MIT-Lizenz veröffentlicht, dh Sie können den Quellcode für Is64BitProcessund Is64BitOperatingSystem(Links für Version 2.0) lesen .
Cristian Ciupitu
51

Dies ist nur eine Implementierung der oben von Bruno Lopez vorgeschlagenen Vorschläge, funktioniert jedoch mit Win2k + allen WinXP-Service Packs. Ich dachte nur, ich würde es posten, damit andere Leute es nicht von Hand rollen mussten. (hätte als Kommentar gepostet, aber ich bin ein neuer Benutzer!)

[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
quelle
49

Die vollständige Antwort lautet wie folgt (sowohl aus Stefan-mg, Ripper234 als auch aus BobbyShaftoes Antwort):

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

Überprüfen Sie zunächst, ob Sie sich in einem 64-Bit-Prozess befinden. Wenn nicht, überprüfen Sie, ob der 32-Bit-Prozess ein Wow64-Prozess ist.

Bruno Lopes
quelle
13
Dies schlägt unter Win2000 und WinXP SP1 und früher fehl. Sie müssen überprüfen, ob die Funktion IsWow64Process () vorhanden ist, bevor Sie sie aufrufen, da sie nur in XP SP2 und Vista / Win7 eingeführt wurde.
user9876
2
@ user9876, zielt (oder hat) noch jemand auf diese antiken Systeme?
CMircea
5
In diesem Beispiel kann die von Process.GetCurrentProcess () zurückgegebene Prozessinstanz nicht entsorgt werden.
Joe
42

Microsoft hat hierfür ein Codebeispiel erstellt:

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

Es sieht aus wie das:

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

Es ist auch eine WMI-Version verfügbar (zum Testen von Remote-Computern).

Synhershko
quelle
1
Beachten Sie, dass dieser Code unter der Microsoft Public License lizenziert ist .
Beladung
WMI-Version ohne verwaltetes .net? Ich würde das gerne sehen, habe es bisher noch nicht gefunden
JohnZaj
16

Sie können auch nach der PROCESSOR_ARCHITECTUREUmgebungsvariablen suchen.

Es existiert entweder nicht oder ist unter 32-Bit-Windows auf "x86" eingestellt.

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
quelle
1
Nur weil Sie einen 64-Bit-Prozessor haben, heißt das nicht, dass Sie ein 64-Bit-Betriebssystem haben
David
2
@David Hier wird die Prozessorarchitektur von Windows gemeldet. nicht die CPU. Siehe ausführliche Erklärung ab "The Code" auf dieser Seite: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley
Nur 2 Cent hinzuzufügen, wenn Sie dies ausführen, und Ihre Anwendung konfiguriert ist, um prefer 32-bitmit Any CPUals Platform Targetdann erhalten Sie x86, aber wenn Sie untick Prefer 32-bites wird Ihnen dann erhalten AMD64.
XAMlMAX
14

Aus dem Blog von Chriz Yuen

C # .Net 4.0 Einführung von zwei neuen Umgebungseigenschaften Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Bitte seien Sie vorsichtig, wenn Sie diese beiden Eigenschaften nutzen. Test auf Windows 7 64-Bit-Computer

//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
quelle
12

Schnellster Weg:

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

Hinweis: Dies ist sehr direkt und funktioniert unter 64-Bit nur dann ordnungsgemäß, wenn das Programm die Ausführung nicht als 32-Bit-Prozess erzwingt (z. B.<Prefer32Bit>true</Prefer32Bit>in den Projekteinstellungen).

BobbyShaftoe
quelle
32
Dies funktioniert nicht - wenn es in 32-Bit-.NET Framework 2.0 unter 64-Bit-Windows ausgeführt wird, wird 32-Bit zurückgegeben.
Stefan Schultze
Richtig, ich habe diese Situation vergessen. Ich habe die Frage bearbeitet, um dies ebenfalls zu erwähnen. Danke stefan-mg.
Marc
1
Das ist nicht richtig; Die Plattform ist möglicherweise 64-Bit, aber Sie arbeiten immer noch im 32-Bit-Modus.
Sebastian Good
11

Versuche dies:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
user2235582
quelle
5
Vielen Dank für Ihre Eingabe, aber bitte lesen Sie die verfügbaren Antworten vor dem Posten, da diese Lösung bereits gegeben ist. Beachten Sie auch, dass die ursprüngliche Frage über .net 2 war, das diese beiden Eigenschaften nicht hat, die nur mit .net 4 eingeführt wurden.
Marc
9

@foobar: Du hast recht, es ist zu einfach;)

In 99% der Fälle erkennen Entwickler mit einem schwachen Systemadministratorhintergrund letztendlich nicht, welche Leistung Microsoft immer für die Aufzählung von Windows bereitgestellt hat.

Systemadministratoren schreiben immer besseren und einfacheren Code, wenn es um einen solchen Punkt geht.

Beachten Sie jedoch, dass die Build-Konfiguration AnyCPU sein muss, damit diese Umgebungsvariable die richtigen Werte auf den richtigen Systemen zurückgibt :

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Dies gibt "X86" unter 32-Bit-Windows und "AMD64" unter 64-Bit-Windows zurück.

SomeSysadmin
quelle
4
Ihre Lösung gibt x86 auf einem MacBook Pro mit Intel i7-3720QM-Mikroprozessor zurück, auf dem Bootcamp mit einer Widows 7 Ultimate-Partition ausgeführt wird. Die Lösung von Stefan Schultze identifizierte den Prozessor ordnungsgemäß als 64-Bit. Ich bin sicher, dass Ihre Lösung auf 99% des Windows-basierten PCs funktioniert. +1 für den Versuch.
Mark Kram
Nee. "x86" auf meinem Windows 7 Pro, 64-Bit-Betriebssystem zurückgegeben.
Hagai L
7

Mithilfe von dotPeek können Sie sehen, wie das Framework dies tatsächlich tut. In diesem Sinne habe ich mir Folgendes ausgedacht:

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

Anwendungsbeispiel:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
quelle
6

Verwenden Sie diese beiden Umgebungsvariablen (Pseudocode):

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
        }

Weitere Informationen finden Sie im Blog-Beitrag HOWTO: Process Bitness erkennen .

Santhosh
quelle
Haben Sie den Teil gesehen, in dem es um .NET und nicht um C / C ++ ging? Und dass dies eine Kompilierungszeit gegenüber einer Laufzeitprüfung ist. Außerdem führt der Code Zuweisungen und keine Vergleiche durch.
Dvallejo
Dieser Code funktioniert unter .NET (getestet unter 2.0). Auf Env-Variablen kann zugegriffen werden von: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432");
andrew.fox
5

Ich habe diesen Check mit Erfolg auf vielen Betriebssystemen verwendet:

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

Dieser Ordner heißt immer "SysWOW64", unabhängig von der Sprache des Betriebssystems. Dies funktioniert für .NET Framework 1.1 oder höher.

Alexandru Dicu
quelle
Und was hindert mich als Benutzer mit Administratorrechten aus einem Ordner namens Erstellen SysWOW64auf ein %windir%auf einem 32 - Bit - OS? Das Vorhandensein eines Ordners bedeutet genau das: dass der Ordner vorhanden ist.
Cogumel0
Wie hoch sind die Chancen, dass ein Benutzer absichtlich einen solchen Ordner erstellt? Dies ist nur eine andere Möglichkeit, um zu überprüfen, ob das Betriebssystem x64 ist.
Alexandru Dicu
Wie hoch ist die Wahrscheinlichkeit, dass Ihr Computer einen Virus bekommt? Da die Chancen recht gering sind, installieren Sie besser keinen Schutz als ... Beim Programmieren geht es nicht darum, etwas zu erstellen, bei dem die Wahrscheinlichkeit eines wissentlichen Versagens gering ist . Es geht darum, etwas zu schaffen, bei dem die Wahrscheinlichkeit gering ist, dass es unwissentlich versagt - und es dann zu reparieren. Die erste heißt schlechte Programmierung / schlechte Implementierung, die zweite heißt Fehler.
Cogumel0
@AlexandruDicu Sie sollten in der Antwort erwähnen, dass dieser Ansatz nicht 100% genau ist und dennoch das Risiko einer falschen Ausgabe besteht, falls der Ordner absichtlich von einer Drittanbieter-App oder einem Benutzer manuell erstellt wird.
Rajesh Mishra
4

Ich muss dies tun, aber ich muss es auch als Administrator aus der Ferne tun können. In beiden Fällen scheint dies für mich ganz gut zu funktionieren:

    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
quelle
4

Dies ist eine Lösung, die auf dem Microsoft-Code unter http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 basiert . Es verwendet Erweiterungsmethoden für die einfache Wiederverwendung von Code.

Einige mögliche Verwendungszwecke sind unten aufgeführt:

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
quelle
Die CodePlex-Verbindung scheint unterbrochen zu sein.
Peter Mortensen
3

Hier ist der direkte Ansatz in C # mit DllImport von dieser Seite .

[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
quelle
Sie müssen immer noch zuerst die
Bruno Lopes
1
Stürzt auch auf einem älteren Betriebssystem ab, da IsWow64Processes nicht existiert.
Polynom
3

Ich verwende den folgenden Code. Hinweis: Es wurde für ein AnyCPU-Projekt erstellt.

    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
quelle
2

Ich fand, dass dies der beste Weg ist, um die Plattform des Systems und den Prozess zu überprüfen:

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

Die erste Eigenschaft gibt true für ein 64-Bit-System und false für 32-Bit zurück. Die zweite Eigenschaft gibt true für 64-Bit-Prozesse und false für 32-Bit-Prozesse zurück.

Diese beiden Eigenschaften sind erforderlich, da Sie 32-Bit-Prozesse auf einem 64-Bit-System ausführen können. Sie müssen daher sowohl nach dem System als auch nach dem Prozess suchen.

OmarElsherif
quelle
1
Setzen Sie ein _ oder einen Buchstaben vor den Variablennamen, wenn Sie möchten, dass er in c # eingebaut wird (Variablennamen beginnen nicht mit Zahlen in c #, soweit meine Idee es mir sagt!)
Chris
2

Alles in Ordnung, aber das sollte auch funktionieren von env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Vielleicht zu einfach ;-)

Peter Mortensen
quelle
2

Hier ist ein WMI-Ansatz ( Windows Management Instrumentation ):

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:
user1054695
quelle
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
quelle
3
Das ist alles schön, aber diese Klasse stammt aus dem Microsoft.UpdateServices.Administration-Namespace, der Microsoft WSUS ist. Ich möchte diese Referenz nicht einfügen, nur um die Plattformbits zu kennen.
Marc
"C: \ Programme \ Microsoft.NET \ SDK \ v2.0 64-Bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico
1

Fügen Sie den folgenden Code in eine Klasse in Ihrem Projekt ein:

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

Verwenden Sie es so:

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

Verwenden Sie diese Option, um die installierte Windows-Architektur abzurufen:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
user885959
quelle
Ich habe keine ProgramFilesX86-Eigenschaft auf w7x64 vs.net 2010
Christian Casutt
0

Angesichts der Tatsache, dass die akzeptierte Antwort sehr komplex ist. Es gibt einfachere Wege. Meins ist eine Variation von Alexandrudicus Antwort. Angesichts der Tatsache, dass 64-Bit-Fenster 32-Bit-Anwendungen in Programmdateien (x86) installieren, können Sie mithilfe von Umgebungsvariablen überprüfen, ob dieser Ordner vorhanden ist (um unterschiedliche Lokalisierungen auszugleichen).

z.B

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

Das ist für mich schneller und einfacher. Da ich auch auf einen bestimmten Pfad unter diesem Ordner zugreifen möchte, der auf der Betriebssystemversion basiert.

John Demetriou
quelle
2
Die akzeptierte Antwort war für .NET 2.0. Wenn Sie mit .NET 4.0 oder neuer arbeiten, verwenden Sie einfach Environment.Is64BitOperatingSystem, wie Sie in der Antwort mit den meisten Stimmen finden.
Marc
Ja, meins ist auch für .net 2.0.
John Demetriou
-2

Genießen ;-)

Function Is64Bit() As Boolean

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

End Function
Majid95
quelle
-1, da dies bei lokalisierten Windows-Installationen nicht funktioniert. Und es verwendet VB.net, während die Frage für C # markiert ist.
Marc
-3

Überprüfen Sie nur, ob "C: \ Programme (x86)" vorhanden ist. Wenn nicht, haben Sie ein 32-Bit-Betriebssystem. Wenn dies der Fall ist, ist das Betriebssystem 64-Bit (Windows Vista oder Windows 7). Es scheint einfach genug ...

John
quelle
5
Stellen Sie sicher, dass Sie den richtigen lokalisierten Verzeichnisnamen von der Win32-API abrufen, anstatt ihn fest zu codieren.
Christian Hayter
Ich würde sagen, das ist eine gute Idee, aber Sie können nicht davon ausgehen, dass ein Benutzer dies aus einem unbekannten Grund niemals tun würde.
GurdeepS
2
Einige schlecht geschriebene Anwendungen werden jetzt ohne Rücksicht auf die Architektur direkt in "Programme (x86)" installiert. Ich habe dieses Verzeichnis zum Beispiel dank SOAPSonar auf meinem 32-Bit-Computer.
Beladung
-4

Ich benutze:

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

Dadurch wird der Pfad abgerufen, in dem Ihre Anwendung gestartet wird, falls Sie sie an verschiedenen Stellen auf dem Computer installiert haben. Sie können auch einfach den allgemeinen C:\Pfad ausführen, da in 99,9% der Computer Windows installiert ist C:\.

Ben G.
quelle
8
Sehr schlechter Ansatz. Was ist, wenn dieses Verzeichnis in Zukunft umbenannt wird? Was ist mit der lokalisierten Version von Windows? In Windows XP heißt Deutsch "Programme" "Programm". Ich bin mir nicht sicher, aber XP 64 kann es daher "Programm (x86)" nennen.
Marc
1
Ich empfehle es nicht, aber Sie könnten das Lokalisierungsproblem umgehen, indem Sie die Umgebungsvariable% ProgramFiles (x86)%
Matthew Lock
-7

Ich benutze eine Version von Folgendem:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
Josh
quelle
6
Dies funktioniert bei nicht englischen XP-Versionen aufgrund des lokalisierten Programmordnernamens nicht.
Daniel Schlößer
Aber auch 64-Bit-Systeme haben diesen Ordner haha
Vorsicht