Come rilevare la piattaforma Windows a 64 bit con .NET?


269

In un'applicazione C # .NET 2.0 utilizzo il seguente codice per rilevare la piattaforma del sistema operativo:

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

Ciò restituisce "Win32NT". Il problema è che restituisce "Win32NT" anche quando è in esecuzione su Windows Vista a 64 bit.

Esiste un altro metodo per conoscere la piattaforma corretta (32 o 64 bit)?

Si noti che dovrebbe anche rilevare 64 bit quando eseguito come applicazione a 32 bit su Windows 64 bit.

Risposte:


200

IntPtr.Size non restituirà il valore corretto se eseguito in .NET Framework 2.0 a 32 bit su Windows a 64 bit (restituirebbe 32 bit).

Come descrive Raymond Chen di Microsoft, devi prima verificare se in esecuzione in un processo a 64 bit (penso che in .NET puoi farlo controllando IntPtr.Size), e se stai eseguendo in un processo a 32 bit, devi comunque deve chiamare la funzione API Win IsWow64Process. Se questo restituisce true, si esegue un processo a 32 bit su Windows a 64 bit.

Raymond Chen di Microsoft: come rilevare a livello di codice se si esegue su Windows a 64 bit

La mia soluzione:

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

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

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

7
Quando viene eseguito su un sistema operativo a 32 bit, qualsiasi chiamata a IsWow64Process genererà un'eccezione poiché tale voce manca da kernel32.dll. Dovresti controllare la soluzione mostrata da codeplex su 1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Ho anche una soluzione basata su quel codice elencato nella parte inferiore di questa pagina, che utilizza metodi di estensione se ti interessa riutilizzando il codice.
dmihailescu,

7
IsWow64Process è stato introdotto con Win XP SP2. Questo codice funziona correttamente se si richiede XP SP2 o una versione più recente.
Marc

3
@dmihailescu, puoi semplicemente usare DoesWin32MethodExist prima di chiamare IsWow64Process, che è ciò che fa l'implementazione .net 4.0 di is64BitOperatingSystem.
noobish,

4
La tua soluzione restituisce il valore corretto su un MacBook Pro con microprocessore Intel i7-3720QM che esegue Bootcamp usando una partizione Widows 7 Ultimate. +1
Mark Kram,

11
Cordiali saluti: a partire da .Net 4.0 puoi semplicemente controllare System.Environment.Is64BitOperatingSystem. Puoi modificarlo nella tua risposta o darmi il permesso di modificarlo nella tua risposta?
Joel Coehoorn,

242

.NET 4 ha due nuove proprietà nella classe Environment, Is64BitProcess e Is64BitOperatingSystem . È interessante notare che se usi Reflector puoi vedere che sono implementati in modo diverso nelle versioni a 32 e 64 bit di mscorlib. La versione a 32 bit restituisce false per Is64BitProcess e chiama IsWow64Process tramite P / Invoke per Is64BitOperatingSystem. La versione a 64 bit restituisce true per entrambi.


5
Invece di Reflector, perché non scaricare semplicemente la fonte. Quindi ricevi i commenti e altre "note".
AMissico,

3
Secondo la fonte di riferimento, fa qualcosa del genere: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(pseudo-codice)
Polinomio

5
Bello. Se l'utente utilizza .NET 4.0 questa è sicuramente la risposta corretta (ovvero Environment.Is64BitOperatingSystem). - La proprietà FYI non sembra essere presente in .NET 3.5.
BrainSlugs83,

4
Questo non risponde alla domanda che dice specificamente .Net 2.0
abbottdev

.NET Core è stato rilasciato sotto licenza MIT, il che significa che puoi leggere il codice sorgente per Is64BitProcesse Is64BitOperatingSystem(collegamenti per la versione 2.0).
Cristian Ciupitu,


51

Questa è solo un'implementazione di quanto suggerito sopra da Bruno Lopez, ma funziona su Win2k + tutti i service pack di WinXP. Ho solo pensato di postarlo in modo che altre persone non lo avessero fatto a mano. (avrebbe pubblicato un commento, ma sono un nuovo utente!)

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

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

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

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

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

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

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

  return null;
}

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

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

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

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

  return isWow64;
}

49

La risposta completa è questa (tratta dalla risposta di entrambi stefan-mg, ripper234 e 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;
    } 

Per prima cosa controlla se stai eseguendo un processo a 64 bit. In caso contrario, controlla se il processo a 32 bit è un processo Wow64.


13
Ciò fallirà in Win2000 e WinXP SP1 e precedenti. È necessario verificare se la funzione IsWow64Process () esiste prima di chiamarla, poiché è stata introdotta solo in XP SP2 e Vista / Win7.
user9876

2
@ user9876, qualcuno (o ha ancora) preso di mira quei sistemi antichi?
CMircea,

5
In questo esempio non è possibile disporre l'istanza Process restituita da Process.GetCurrentProcess ().
Joe,

42

Microsoft ha inserito un esempio di codice per questo:

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

Sembra così:

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

È disponibile anche una versione WMI (per testare macchine remote).


1
Si noti che questo codice è concesso in licenza con Microsoft Public License .
ladenedge,

Versione WMI senza .net gestito? Mi piacerebbe vederlo, non l'ho trovato finora
JohnZaj,

16

Puoi anche verificare la PROCESSOR_ARCHITECTUREvariabile di ambiente.

O non esiste o è impostato su "x86" su Windows a 32 bit.

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

1
Solo perché hai un processore a 64 bit non significa che hai un sistema operativo a 64 bit
David

2
@David Questo riporta l'architettura del processore di Windows; non la CPU. Vedi spiegazione dettagliata a partire da "Il codice" in questa pagina: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley

Solo per aggiungere 2 centesimi, quando esegui questo, e la tua app è configurata prefer 32-bitcon Any CPUcome la tua Platform Targetallora otterrai x86, ma se lo deselezioni Prefer 32-bitotterrai AMD64.
XAMlMAX

14

Dal blog di Chriz Yuen

C # .Net 4.0 Sono state introdotte due nuove proprietà di ambiente Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Si prega di fare attenzione quando si utilizzano entrambe le proprietà. Test su Windows 7 a 64 bit

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

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

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

12

Il modo più veloce:

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

Nota: questo è molto diretto e funziona correttamente su 64 bit solo se il programma non forza l'esecuzione come processo a 32 bit (ad es. Attraverso<Prefer32Bit>true</Prefer32Bit>le impostazioni del progetto).


32
Questo non funzionerà - se eseguito in .NET Framework 2.0 a 32 bit su Windows a 64 bit, restituirà 32 bit.
Stefan Schultze,

Bene, ho dimenticato questa situazione. Ho modificato la domanda per menzionare anche questo. Grazie stefan-mg.
Marc

1
Questo non è corretto; la piattaforma potrebbe essere a 64 bit ma stai ancora eseguendo la modalità a 32 bit.
Sebastian Good,

11

Prova questo:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess

5
Grazie per il tuo contributo, ma ti preghiamo di leggere le risposte disponibili prima di pubblicare come questa soluzione è già stata data. Si noti inoltre che la domanda originale riguardava .net 2 che non ha queste due proprietà che sono state introdotte solo con .net 4.
Marc

9

@foobar: hai ragione, è troppo facile;)

Nel 99% dei casi, gli sviluppatori con un background di amministratore di sistema debole non riescono a realizzare il potere che Microsoft ha sempre fornito a chiunque di enumerare Windows.

Gli amministratori di sistema scriveranno sempre un codice migliore e più semplice quando si arriva a questo punto.

Tuttavia, una cosa da notare, costruire la configurazione deve essere AnyCPU per questa variabile di ambiente per restituire i valori corretti sui sistemi corretti:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Ciò restituirà "X86" su Windows a 32 bit e "AMD64" su Windows a 64 bit.


4
La tua soluzione restituisce x86 su un MacBook Pro con microprocessore Intel i7-3720QM che esegue Bootcamp con una partizione Widows 7 Ultimate. La soluzione di Stefan Schultze ha identificato correttamente il processore a 64 bit. Sono sicuro che la tua soluzione funziona sul 99% del PC basato su Windows. +1 per provare.
Mark Kram,

No. restituito "x86" sul mio sistema operativo Windows 7 pro a 64 bit.
Hagai L

7

L'uso di dotPeek aiuta a vedere come lo fa effettivamente il framework. Con questo in mente, ecco cosa ho escogitato:

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

Esempio di utilizzo:

EnvironmentHelper.Is64BitOperatingSystem();

6

Utilizzare queste due variabili di ambiente (pseudo codice):

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
        }

Fare riferimento al post del blog HOWTO: Detect Process Bitness .


Hai visto la parte in cui la domanda riguardava .NET e non C / C ++? E che questo è un tempo di compilazione rispetto a un controllo di runtime. Inoltre, il codice sta eseguendo il compito e non i confronti.
dvallejo,

Questo codice funziona su .NET (testato su 2.0). Le variabili Env sono accessibili da: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ( "PROCESSOR_ARCHITEW6432");
andrew.fox

5

Ho usato questo controllo con successo su molti sistemi operativi:

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

Questa cartella è sempre denominata "SysWOW64", indipendentemente dalla lingua del sistema operativo. Funziona con .NET Framework 1.1 o versioni successive.


E cosa mi impedisce come utente con diritti amministrativi di creare una cartella chiamata SysWOW64su un %windir%sistema operativo a 32 bit? La presenza di una cartella significa esattamente questo: che la cartella è presente.
cogumel0,

Quali sono le possibilità che un utente crei una tale cartella di proposito? Questo è solo un modo diverso per verificare se il sistema operativo è x64.
Alexandru Dicu,

Quali sono le possibilità che il tuo computer abbia un virus? Dato che le possibilità sono abbastanza basse, meglio non installare alcuna protezione quindi ... La programmazione non riguarda la creazione di qualcosa che ha basse probabilità di fallire consapevolmente . Si tratta di creare qualcosa che ha basse probabilità di fallire inconsapevolmente - e quindi risolverlo. Il primo si chiama cattiva programmazione / cattiva implementazione, il secondo si chiama bug.
cogumel0,

@AlexandruDicu Dovresti menzionare nella risposta che questo approccio non è accurato al 100% e rischia comunque di dare un output errato nel caso in cui la cartella venga creata apposta da qualsiasi app o utente di terze parti manualmente.
Rajesh Mishra,

4

Devo farlo, ma devo anche essere in grado come amministratore di farlo da remoto, in entrambi i casi questo sembra funzionare abbastanza bene per me:

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

4

Questa è una soluzione basata sul codice di Microsoft all'indirizzo http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Utilizza metodi di estensione per un facile riutilizzo del codice.

Di seguito sono riportati alcuni possibili utilizzi:

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

Il collegamento CodePlex sembra essere rotto.
Peter Mortensen,

3

Ecco l'approccio diretto in C # usando DllImport da questa pagina .

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

Devi ancora controllare prima le dimensioni del puntatore, altrimenti controlla solo se si tratta di un processo a 32 bit su un sistema a 64 bit
Bruno Lopes

1
Si arresta anche in modo anomalo su un sistema operativo precedente, poiché IsWow64Processnon esiste.
Polinomio

3

Sto usando il seguente codice. Nota: è realizzato per un progetto AnyCPU.

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

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

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

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

2

Ho scoperto che questo è il modo migliore per verificare la piattaforma del sistema e il processo:

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

La prima proprietà restituisce true per il sistema a 64 bit e false per 32 bit. La seconda proprietà restituisce true per il processo a 64 bit e false per 32 bit.

La necessità di queste due proprietà è perché è possibile eseguire processi a 32 bit sul sistema a 64 bit, quindi sarà necessario verificare sia il sistema che il processo.


1
metti una _ o una lettera davanti al nome della variabile se vuoi che sia compilata in c # (i nomi delle variabili non iniziano con i numeri in c # per quanto mi dice il mio ide!)
Chris,

2

Tutto bene, ma questo dovrebbe funzionare anche da env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Troppo facile, forse ;-)


2

Ecco un approccio alla Strumentazione gestione 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:

1

OSInfo.Bits

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

3
È tutto carino, ma questa classe proviene dallo spazio dei nomi Microsoft.UpdateServices.Administration che è Microsoft WSUS. Non mi piace includere questo riferimento solo per conoscere i bit della piattaforma.
Marc,

"C: \ Programmi \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico

1

Includi il seguente codice in una classe nel tuo progetto:

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

Usalo così:

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

0

Usa questo per ottenere l'architettura Windows installata:

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

non ho una proprietà ProgramFilesX86 su w7x64 vs.net 2010
Christian Casutt

0

Dato che la risposta accettata è molto complessa. Ci sono modi più semplici. Il mio è una variante della risposta di alexandrudicu. Dato che Windows a 64 bit installa applicazioni a 32 bit in Programmi (x86), puoi verificare se esiste quella cartella, usando le variabili di ambiente (per compensare diverse localizzazioni)

per esempio

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

Questo per me è più veloce e più semplice. Dato che desidero anche accedere a un percorso specifico in quella cartella in base alla versione del sistema operativo.


2
La risposta accettata era per .NET 2.0. Se utilizzi .NET 4.0 o versioni successive, utilizza Environment.Is64BitOperatingSystem come puoi trovare nella risposta con la maggior parte dei voti.
Marc

Sì, il mio è anche per .net 2.0.
John Demetriou,

-2

Godere ;-)

Function Is64Bit() As Boolean

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

End Function

-1 poiché non funzionerà con installazioni Windows localizzate. E utilizza VB.net mentre la domanda è taggata per C #.
Marc

-3

Verifica se esiste "C: \ Programmi (x86)". In caso contrario, sei su un sistema operativo a 32 bit. In tal caso, il sistema operativo è a 64 bit (Windows Vista o Windows 7). Sembra abbastanza semplice ...


5
Assicurarsi di recuperare il nome di directory localizzato corretto dall'API Win32 anziché codificarlo.
Christian Hayter,

Direi che è una buona idea, ma non puoi presumere che un utente non lo farebbe mai per qualche oscuro motivo.
GurdeepS

2
Alcune applicazioni scritte male vengono ora installate direttamente in "Programmi (x86)" senza riguardo all'architettura. Ho quella directory sulla mia macchina a 32 bit grazie ad esempio a SOAPSonar.
ladenedge,

-4

Io uso:

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

Ciò ottiene il percorso in cui l'applicazione viene avviata nel caso in cui sia installata in vari punti del computer. Inoltre, potresti semplicemente fare il C:\percorso generale poiché il 99,9% dei computer là fuori ha installato Windows C:\.


8
Approccio pessimo. E se in futuro questa directory verrà rinominata? Che dire della versione localizzata di Windows? In Windows XP il tedesco "Programmi" si chiama "Programma". Non sono sicuro ma XP 64 potrebbe quindi chiamarlo "Programma (x86)".
Marc

1
Non lo consiglio, ma potresti aggirare il problema della localizzazione espandendo la var ambientale ProgramFiles (x86)%
Matthew Lock

-7

Uso una versione di quanto segue:

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

6
Questo non funziona su versioni XP non inglesi a causa del nome delle cartelle di programma localizzato.
Daniel Schlößer,

Ma anche i sistemi a 64 bit hanno questa cartella haha
attentnow1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.