Comment détecter la plate-forme Windows 64 bits avec .NET?

269

Dans une application .NET 2.0 C #, j'utilise le code suivant pour détecter la plate-forme du système d'exploitation:

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

Cela renvoie "Win32NT". Le problème est qu'il renvoie "Win32NT" même lors de l'exécution sur Windows Vista 64 bits.

Existe-t-il une autre méthode pour connaître la bonne plateforme (32 ou 64 bits)?

Notez qu'il doit également détecter 64 bits lorsqu'il est exécuté en tant qu'application 32 bits sur Windows 64 bits.

Marc
la source

Réponses:

200

IntPtr.Size ne renverra pas la valeur correcte s'il est exécuté dans .NET Framework 2.0 32 bits sur Windows 64 bits (il retournerait 32 bits).

Comme le décrit Raymond Chen de Microsoft, vous devez d'abord vérifier s'il s'exécute dans un processus 64 bits (je pense que dans .NET, vous pouvez le faire en vérifiant IntPtr.Size), et si vous exécutez dans un processus 32 bits, vous avez toujours doivent appeler la fonction Win API IsWow64Process. Si cela retourne vrai, vous exécutez un processus 32 bits sur Windows 64 bits.

Raymond Chen de Microsoft: comment détecter par programme si vous utilisez Windows 64 bits

Ma solution:

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
la source
7
Lors de l'exécution sur un système d'exploitation 32 bits, tout appel à IsWow64Process lèvera une exception car cette entrée est manquante dans kernel32.dll. Vous devriez vérifier la solution présentée par codeplex à 1code.codeplex.com/SourceControl/changeset/view/39074#842775 . J'ai également une solution basée sur ce code répertorié au bas de cette page, qui utilise des méthodes d'extension si vous vous souciez de réutiliser le code.
dmihailescu
7
IsWow64Process a été introduit avec Win XP SP2. Ce code fonctionne correctement si vous avez besoin de XP SP2 ou d'une version plus récente.
Marc
3
@dmihailescu, vous pouvez simplement utiliser DoesWin32MethodExist avant d'appeler IsWow64Process, ce que fait l'implémentation .net 4.0 d'is64BitOperatingSystem.
noobish
4
Votre solution renvoie la valeur correcte sur un MacBook Pro avec un microprocesseur Intel i7-3720QM exécutant Bootcamp à l'aide d'une partition Widows 7 Ultimate. +1
Mark Kram
11
FYI: à partir de .Net 4.0, vous pouvez simplement vérifier System.Environment.Is64BitOperatingSystem. Pouvez-vous le modifier dans votre réponse ou me donner la permission de le modifier dans votre réponse?
Joel Coehoorn
242

.NET 4 possède deux nouvelles propriétés dans la classe Environnement, Is64BitProcess et Is64BitOperatingSystem . Fait intéressant, si vous utilisez Reflector, vous pouvez voir qu'ils sont implémentés différemment dans les versions 32 bits et 64 bits de mscorlib. La version 32 bits renvoie false pour Is64BitProcess et appelle IsWow64Process via P / Invoke pour Is64BitOperatingSystem. La version 64 bits renvoie juste vrai pour les deux.

Phil Devaney
la source
5
Au lieu de Reflector, pourquoi ne pas simplement télécharger la source. Ensuite, vous obtenez les commentaires et autres "notes".
AMissico
3
Selon la source de référence, il fait quelque chose comme ceci: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(pseudo-code)
Polynôme
5
Agréable. Si l'utilisateur utilise .NET 4.0, c'est certainement la bonne réponse (c'est-à-dire Environment.Is64BitOperatingSystem). - La propriété FYI ne semble pas exister dans .NET 3.5.
BrainSlugs83
4
Cela ne répond pas à la question qui dit spécifiquement .Net 2.0
abbottdev
.NET Core a été publié sous la licence MIT, ce qui signifie que vous pouvez lire le code source de Is64BitProcesset Is64BitOperatingSystem(liens pour la version 2.0).
Cristian Ciupitu
51

Ceci n'est qu'une implémentation de ce qui est suggéré ci-dessus par Bruno Lopez, mais fonctionne sur Win2k + tous les Service Packs WinXP. Je pensais juste que je le posterais pour que les autres ne l'aient pas roulé à la main. (aurait posté un commentaire, mais je suis un nouvel utilisateur!)

[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
la source
49

La réponse complète est la suivante (tirée à la fois de stefan-mg, ripper234 et de la réponse de 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;
    } 

Vérifiez d'abord si vous êtes dans un processus 64 bits. Si ce n'est pas le cas, vérifiez si le processus 32 bits est un processus Wow64.

Bruno Lopes
la source
13
Cela échouera sous Win2000 et WinXP SP1 et versions antérieures. Vous devez vérifier si la fonction IsWow64Process () existe avant de l'appeler, car elle n'a été introduite que dans XP SP2 et Vista / Win7.
user9876
2
@ user9876, quelqu'un cible-t-il (ou a-t-il encore) ciblé ces anciens systèmes?
CMircea
5
Cet exemple ne parvient pas à supprimer l'instance de processus renvoyée par Process.GetCurrentProcess ().
Joe
42

Microsoft a mis un exemple de code pour cela:

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

Cela ressemble à ceci:

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

Il existe également une version WMI (pour tester les machines distantes).

synhershko
la source
1
Notez que ce code est sous licence Microsoft Public License .
ladenedge
Version WMI sans .net géré? J'aimerais voir ça, je ne l'ai pas trouvé jusqu'à présent
JohnZaj
16

Vous pouvez également vérifier la PROCESSOR_ARCHITECTUREvariable d'environnement.

Il n'existe pas ou est défini sur "x86" sous Windows 32 bits.

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
la source
1
Ce n'est pas parce que vous avez un processeur 64 bits que vous avez un système d'exploitation 64 bits
David
2
@David Ceci rapporte l'architecture de processeur de Windows; pas le CPU. Voir l'explication détaillée à partir de "The Code" sur cette page: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley
Juste pour ajouter 2 cents, lorsque vous exécutez cela, et votre application est configurée pour prefer 32-bitavec Any CPUvotre, Platform Targetvous obtiendrez x86, mais si vous la décochez Prefer 32-bit, vous l'obtiendrez AMD64.
XAMlMAX
14

Du blog de Chriz Yuen

C # .Net 4.0 Présentation de deux nouvelles propriétés d'environnement Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Veuillez faire attention lorsque vous utilisez ces deux propriétés. Test sur 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
electricbah
la source
12

La façon la plus rapide:

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

Remarque: ceci est très direct et fonctionne correctement sur 64 bits uniquement si le programme ne force pas l'exécution en tant que processus 32 bits (par exemple<Prefer32Bit>true</Prefer32Bit>dans les paramètres du projet).

BobbyShaftoe
la source
32
Cela ne fonctionnera pas - s'il s'exécute dans .NET Framework 2.0 32 bits sur Windows 64 bits, il renverra 32 bits.
Stefan Schultze
Bon j'ai oublié cette situation. J'ai édité la question pour le mentionner également. Merci stefan-mg.
Marc
1
Ce n'est pas correct; la plate-forme peut être 64 bits mais vous êtes toujours en cours d'exécution en mode 32 bits.
Sebastian Good
11

Essaye ça:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
user2235582
la source
5
Merci pour votre contribution, mais veuillez lire les réponses disponibles avant de poster car cette solution est déjà proposée. A noter également que la question initiale était sur le .net 2 qui ne présente pas ces deux propriétés qui ont été introduites seulement .net 4.
Marc
9

@foobar: Tu as raison, c'est trop facile;)

Dans 99% des cas, les développeurs ayant des antécédents d'administrateur système faibles ne parviennent finalement pas à réaliser le pouvoir que Microsoft a toujours fourni à quiconque pour énumérer Windows.

Les administrateurs système écriront toujours du code meilleur et plus simple à ce sujet.

Néanmoins, une chose à noter, la configuration de construction doit être AnyCPU pour que cette variable d'environnement renvoie les valeurs correctes sur les bons systèmes:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Cela renverra "X86" sur Windows 32 bits et "AMD64" sur Windows 64 bits.

SomeSysadmin
la source
4
Votre solution renvoie x86 sur un MacBook Pro avec un microprocesseur Intel i7-3720QM exécutant Bootcamp avec une partition Widows 7 Ultimate. La solution de Stefan Schultze a correctement identifié le processeur comme un 64 bits. Je suis sûr que votre solution fonctionne sur 99% des PC Windows. +1 pour avoir essayé.
Mark Kram
Nan. retourné "x86" sur mon système d'exploitation Windows 7 Pro, 64 bits.
Hagai L
7

L'utilisation de dotPeek permet de voir comment le framework le fait réellement. Dans cet esprit, voici ce que j'ai trouvé:

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

Exemple d'utilisation:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
la source
6

Utilisez ces deux variables d'environnement (pseudo-code):

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
        }

Reportez-vous au billet de blog HOWTO: Detect Process Bitness .

Santhosh
la source
Avez-vous vu la partie où la question portait sur .NET et non sur C / C ++? Et qu'il s'agit d'un temps de compilation par rapport à une vérification d'exécution. En outre, le code effectue des affectations et non des comparaisons.
dvallejo
Ce code fonctionne sur .NET (testé sur 2.0). Les variables Env sont accessibles par: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432");
andrew.fox
5

J'ai utilisé cette vérification avec succès sur de nombreux systèmes d'exploitation:

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

Ce dossier est toujours nommé "SysWOW64", quelle que soit la langue du système d'exploitation. Cela fonctionne pour .NET Framework 1.1 ou supérieur.

Alexandru Dicu
la source
Et qu'est-ce qui m'empêche en tant qu'utilisateur disposant de droits administratifs de créer un dossier appelé SysWOW64sur un %windir%système d'exploitation 32 bits? La présence d'un dossier signifie exactement cela: que le dossier est présent.
cogumel0
Quelles sont les chances qu'un utilisateur crée un tel dossier exprès? C'est juste une façon différente de vérifier si le système d'exploitation est x64.
Alexandru Dicu
Quelles sont les chances que votre ordinateur soit infecté par un virus? Puisque les chances sont assez faibles, mieux vaut ne pas installer de protection alors ... La programmation ne consiste pas à créer quelque chose qui a de faibles chances d' échouer sciemment . Il s'agit de créer quelque chose qui a de faibles chances d' échouer sans le savoir - puis de le réparer. Le premier est appelé mauvaise programmation / mauvaise implémentation, le second est appelé bogue.
cogumel0
@AlexandruDicu Vous devez mentionner dans la réponse que cette approche n'est pas précise à 100% et risque toujours de donner une sortie erronée si le dossier est créé exprès par une application ou un utilisateur tiers manuellement.
Rajesh Mishra
4

Je dois le faire, mais je dois également pouvoir en tant qu'administrateur le faire à distance, dans les deux cas, cela semble fonctionner très bien pour moi:

    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
la source
4

Il s'agit d'une solution basée sur le code de Microsoft à l' adresse http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Il utilise des méthodes d'extension pour une réutilisation facile du code.

Une utilisation possible est indiquée ci-dessous:

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
la source
Le lien CodePlex semble rompu.
Peter Mortensen
3

Voici l'approche directe en C # en utilisant DllImport à partir de cette page .

[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
la source
Vous devez toujours vérifier la taille du pointeur en premier, sinon il vérifie simplement s'il s'agit d'un processus 32 bits sur un système 64 bits
Bruno Lopes
1
Se bloque également sur un ancien système d'exploitation, car il IsWow64Processn'existe pas.
Polynôme
3

J'utilise le code de suivi. Remarque: il est conçu pour un projet 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
la source
2

J'ai trouvé que c'était la meilleure façon de vérifier la plate-forme du système et le processus:

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

La première propriété renvoie true pour un système 64 bits et false pour 32 bits. La deuxième propriété renvoie true pour le processus 64 bits et false pour 32 bits.

La nécessité de ces deux propriétés est que vous pouvez exécuter des processus 32 bits sur un système 64 bits, vous devrez donc vérifier à la fois le système et le processus.

OmarElsherif
la source
1
mettez un _ ou une lettre devant le nom de la variable si vous voulez qu'il soit construit en c # (les noms de variables ne commencent pas par des chiffres en c # pour autant que mon idée me le dise!)
Chris
2

Très bien, mais cela devrait également fonctionner à partir de env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Trop facile, peut-être ;-)

Peter Mortensen
la source
2

Voici une approche WMI ( 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
la source
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
la source
3
C'est très bien, mais cette classe provient de l'espace de noms Microsoft.UpdateServices.Administration qui est Microsoft WSUS. Je n'aime pas inclure cette référence juste pour connaître les bits de la plateforme.
Marc
"C: \ Program Files \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico
1

Incluez le code suivant dans une classe de votre projet:

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

Utilisez-le comme ceci:

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

Utilisez ceci pour obtenir l'architecture Windows installée:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
user885959
la source
je n'ai pas de propriété ProgramFilesX86 sur w7x64 vsnet 2010
Christian Casutt
0

Étant donné que la réponse acceptée est très complexe. Il existe des moyens plus simples. Le mien est une variante de la réponse d'Alexandrudicu. Étant donné que les fenêtres 64 bits installent des applications 32 bits dans Program Files (x86), vous pouvez vérifier si ce dossier existe, en utilisant des variables d'environnement (pour compenser les différentes localisations)

par exemple

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

Pour moi, c'est plus rapide et plus simple. Étant donné que je souhaite également accéder à un chemin spécifique sous ce dossier en fonction de la version du système d'exploitation.

John Demetriou
la source
2
La réponse acceptée était pour .NET 2.0. Si vous êtes sur .NET 4.0 ou plus récent, utilisez simplement Environment.Is64BitOperatingSystem comme vous pouvez le trouver dans la réponse avec la plupart des votes.
Marc
Oui, le mien est aussi pour .net 2.0.
John Demetriou
-2

Prendre plaisir ;-)

Function Is64Bit() As Boolean

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

End Function
Majid95
la source
-1 car cela ne fonctionnera pas sur les installations Windows localisées. Et il utilise VB.net alors que la question est balisée pour C #.
Marc
-3

Il suffit de voir si le "C: \ Program Files (x86)" existe. Sinon, vous êtes sur un système d'exploitation 32 bits. Si c'est le cas, le système d'exploitation est 64 bits (Windows Vista ou Windows 7). Cela semble assez simple ...

John
la source
5
Assurez-vous de récupérer le nom de répertoire localisé correct à partir de l'API Win32 au lieu de le coder en dur.
Christian Hayter
Je dirais que c'est une bonne idée, mais vous ne pouvez pas supposer qu'un utilisateur ne ferait jamais cela pour une raison obscure.
GurdeepS
2
Certaines applications mal écrites sont désormais installées directement dans "Program Files (x86)" sans tenir compte de l'architecture. J'ai ce répertoire sur ma machine 32 bits grâce à SOAPSonar, par exemple.
ladenedge
-4

J'utilise:

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

Cela permet d'accéder au chemin où votre application est lancée au cas où vous l'avez installée à différents endroits sur l'ordinateur. En outre, vous pouvez simplement suivre le C:\chemin général , car 99,9% des ordinateurs ont Windows installé C:\.

Ben G
la source
8
Très mauvaise approche. Et si à l'avenir ce répertoire était renommé? Qu'en est-il de la version localisée de Windows? Dans Windows XP, l'allemand "Program Files" est appelé "Program". Je ne suis pas sûr mais XP 64 peut donc l'appeler "Programme (x86)".
Marc
1
Je ne le recommande pas, mais vous pouvez contourner le problème de localisation en développant la variable environnementale% ProgramFiles (x86)%
Matthew Lock
-7

J'utilise une version des éléments suivants:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
Josh
la source
6
Cela ne fonctionne pas sur les versions XP non anglais en raison du nom localisé des dossiers de programme.
Daniel Schlößer
Mais même les systèmes 64 bits ont ce dossier haha
prudencenow1