Come determinare a livello di codice se un particolare processo è a 32 o 64 bit


102

In che modo la mia applicazione C # può verificare se una particolare applicazione / processo (nota: non il processo corrente) è in esecuzione in modalità a 32 o 64 bit?

Ad esempio, potrei voler interrogare un particolare processo per nome, ad esempio "abc.exe", o in base al numero ID del processo.


Si prega di inserire sempre la lingua come tag; Lo cambierò ora in questo post. :-)
Dean J

3
Si prega di chiarire se si desidera sapere che il processo corrente è a 64 bit o si sta interrogando un altro processo?
Mehrdad Afshari,

Risposte:


177

Uno dei modi più interessanti che ho visto è questo:

if (IntPtr.Size == 4)
{
    // 32-bit
}
else if (IntPtr.Size == 8)
{
    // 64-bit
}
else
{
    // The future is now!
}

Per scoprire se ALTRI processi sono in esecuzione nell'emulatore a 64 bit (WOW64), usa questo codice:

namespace Is64Bit
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    internal static class Program
    {
        private static void Main()
        {
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    Console.WriteLine(p.ProcessName + " is " + (p.IsWin64Emulator() ? string.Empty : "not ") + "32-bit");
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode != 0x00000005)
                    {
                        throw;
                    }
                }
            }

            Console.ReadLine();
        }

        private static bool IsWin64Emulator(this Process process)
        {
            if ((Environment.OSVersion.Version.Major > 5)
                || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1)))
            {
                bool retVal;

                return NativeMethods.IsWow64Process(process.Handle, out retVal) && retVal;
            }

            return false; // not on 64-bit Windows Emulator
        }
    }

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
    }
}

8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) Ed è per questo che Microsoft deve creare spessori di compatibilità delle versioni bugie - per aggirare i bug nel codice come quello. Cosa succede quando esce Windows Vista (6.0)? E le persone poi parlano male di Microsoft per aver creato Windows 7 versione 6.1 anziché 7.0, risolve così tanti bug di compatibilità delle app.
Ian Boyd

4
Il nome della funzione IsWin64 è un po 'fuorviante, penso. Restituisce vero se il processo a 32 bit è in esecuzione con il sistema operativo x64.
Denis The Menace

2
Perché usare processHandle = Process.GetProcessById(process.Id).Handle;invece che solo processHandle = process.Handle;?
Jonathon Reinhart

1
@JonathonReinhart, beh, non è solo una bella domanda. Non ne ho idea. Dev'essere stato un rudere da un cambiamento di cose da fare in un modo all'altro. Grazie per averlo trovato!
Jesse C. Slicer

1
Questa risposta è semplicemente errata; e restituire false invece di sollevare un'eccezione in caso di errore è una progettazione pessima.
user626528

141

Se stai usando .Net 4.0, è una riga per il processo corrente:

Environment.Is64BitProcess

Vedere Environment.Is64BitProcessProperty (MSDN).


2
Potresti inserire il codice di Is64BitProcess? Forse posso usare quello che fa per capire se sto eseguendo come un processo a 64 bit.
Ian Boyd

1
@Ian, dubito che Sam sarebbe legalmente autorizzato a pubblicare codice MS su questo forum. Non sono sicuro del contenuto esatto della loro licenza di riferimento, ma sono abbastanza sicuro che proibisca la riproduzione del codice ovunque.
ProfK

3
@Ian qualcuno ha fatto quel lavoro per te: stackoverflow.com/questions/336633/…
Robert MacLean

4
L'OP ha chiesto espressamente di interrogare un altro processo, non il processo corrente.
Harry Johnston

1
Tieni presente che Microsoft ha pubblicato il codice per Is64BitProcess( referencesource.microsoft.com/#mscorlib/system/environment.cs ). Tuttavia, è solo un'istruzione di ritorno hard-coded, controllata dal simbolo di compilazione.
Brian

20

La risposta selezionata non è corretta in quanto non esegue ciò che è stato chiesto. Controlla invece se un processo è un processo x86 in esecuzione su OS x64; quindi restituirà "false" per un processo x64 su sistema operativo x64 o x86 in esecuzione su sistema operativo x86.
Inoltre, non gestisce correttamente gli errori.

Ecco un metodo più corretto:

internal static class NativeMethods
{
    // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
    public static bool Is64Bit(Process process)
    {
        if (!Environment.Is64BitOperatingSystem)
            return false;
        // if this method is not available in your version of .NET, use GetNativeSystemInfo via P/Invoke instead

        bool isWow64;
        if (!IsWow64Process(process.Handle, out isWow64))
            throw new Win32Exception();
        return !isWow64;
    }

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

1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"restituirà sempre true per un processo a 32 bit. Meglio da usare System.Environment.Is64BitOperatingSystemse .NET4 è supportato
Aizzat Suhardi

10

Puoi controllare la dimensione di un puntatore per determinare se è a 32 bit o 64 bit.

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();

6
Al momento in cui questa risposta è stata pubblicata per la prima volta non era molto chiara, ma l'OP voleva sapere come interrogare un altro processo piuttosto che il processo corrente.
Harry Johnston

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

5
L'OP ha chiesto specificamente come interrogare un altro processo, non il processo corrente.
Harry Johnston

1

Ecco il controllo di una riga.

bool is64Bit = IntPtr.Size == 8;

6
L'OP ha chiesto specificamente come interrogare un altro processo, non il processo corrente.
Harry Johnston

0

Mi piace usare questo:

string e = Environment.Is64BitOperatingSystem

In questo modo se ho bisogno di individuare o verificare un file posso scrivere facilmente:

string e = Environment.Is64BitOperatingSystem

       // If 64 bit locate the 32 bit folder
       ? @"C:\Program Files (x86)\"

       // Else 32 bit
       : @"C:\Program Files\";

13
che dire del processo a 32 bit nella macchina OS a 64 bit?
Kiquenet

3
È davvero così difficile da usare al Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)posto di `C: \ Program Files` hardcoded?
Luaan

2
Mai "file di programma" hardcoded, perché è una stringa localizzabile. Αρχεία Εφαρμογών, Arquivos de Programas, ecc.
stevieg
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.