Comment déterminer par programme si un processus particulier est 32 bits ou 64 bits

102

Comment mon application C # peut-elle vérifier si une application / un processus particulier (note: pas le processus actuel) s'exécute en mode 32 bits ou 64 bits?

Par exemple, je pourrais vouloir interroger un processus particulier par son nom, c'est-à-dire «abc.exe», ou en fonction du numéro d'identification du processus.

satya
la source
Veuillez toujours mettre la langue sous forme de balise; Je vais changer cela maintenant sur ce post. :-)
Dean J
3
Veuillez préciser si vous voulez savoir que le processus actuel est 64 bits ou si vous interrogez un autre processus?
Mehrdad Afshari
Dupelicate: stackoverflow.com/questions/266082/…
Lawrence Johnston

Réponses:

177

L'une des façons les plus intéressantes que j'ai vues est la suivante:

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

Pour savoir si AUTRES processus s'exécutent dans l'émulateur 64 bits (WOW64), utilisez ce code:

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);
    }
}
Jesse C. Slicer
la source
8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) Et c'est pourquoi Microsoft doit créer des shims de compatibilité de version - pour contourner les bogues dans un code comme celui-là. Que se passe-t-il lorsque Windows Vista (6.0) sort? Et les gens ont ensuite critiqué Microsoft pour avoir créé Windows 7 version 6.1 plutôt que 7.0, il corrige tant de bogues de compatibilité d'application.
Ian Boyd
4
Le nom de la fonction IsWin64 est un peu trompeur, je pense. Il renvoie vrai si le processus 32 bits s'exécute sous le système d'exploitation x64.
Denis The Menace
2
Pourquoi utiliser processHandle = Process.GetProcessById(process.Id).Handle;au lieu de juste processHandle = process.Handle;?
Jonathon Reinhart
1
@JonathonReinhart n'est pas juste une bonne question. Je n'ai aucune idée. Cela a dû être le vestige d'un changement de façon de faire les choses d'une façon à une autre. Merci d'avoir trouvé ça!
Jesse C. Slicer
1
Cette réponse est tout simplement incorrecte; et renvoyer false au lieu de lever une exception en cas d'erreur est une très mauvaise conception.
user626528
141

Si vous utilisez .Net 4.0, il s'agit d'une ligne unique pour le processus actuel:

Environment.Is64BitProcess

Voir Environment.Is64BitProcessProperty (MSDN).

Sam
la source
2
Pourriez-vous poster le code de Is64BitProcess? Peut-être que je peux utiliser ce qu'il fait pour savoir si je suis en cours d'exécution en tant que processus 64 bits.
Ian Boyd
1
@Ian, je doute que Sam soit légalement autorisé à publier du code MS sur ce forum. Je ne suis pas sûr du contenu exact de leur licence de référence, mais je suis presque sûr qu'elle interdit la reproduction du code n'importe où.
ProfK
3
@Ian quelqu'un a fait ce travail pour vous: stackoverflow.com/questions/336633/…
Robert MacLean
4
Le PO a spécifiquement demandé d'interroger un autre processus, pas le processus actuel.
Harry Johnston
1
Notez que Microsoft a publié le code pour Is64BitProcess( referencesource.microsoft.com/#mscorlib/system/environment.cs ). Cependant, il ne s'agit que d'une instruction return codée en dur, contrôlée par le symbole de compilation.
Brian
20

La réponse sélectionnée est incorrecte car elle ne fait pas ce qui a été demandé. Il vérifie si un processus est un processus x86 exécuté sur un système d'exploitation x64 à la place; il retournera donc "false" pour un processus x64 sur un système d'exploitation x64 ou un processus x86 fonctionnant sur un système d'exploitation x86.
En outre, il ne gère pas correctement les erreurs.

Voici une méthode plus correcte:

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);
}
user626528
la source
1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"retournera toujours vrai pour un processus 32 bits. Mieux vaut utiliser System.Environment.Is64BitOperatingSystemsi .NET4 est pris en charge
Aizzat Suhardi
10

Vous pouvez vérifier la taille d'un pointeur pour déterminer s'il s'agit de 32 bits ou 64 bits.

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();
Darwyn
la source
6
Au moment où cette réponse a été publiée pour la première fois, ce n'était pas très clair, mais le PO voulait savoir comment interroger un autre processus plutôt que le processus actuel.
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;
}
Praveen MB
la source
5
Le PO a spécifiquement demandé comment interroger un autre processus, pas le processus actuel.
Harry Johnston
1

Voici la vérification en une ligne.

bool is64Bit = IntPtr.Size == 8;
Vikram Bose
la source
6
Le PO a spécifiquement demandé comment interroger un autre processus, pas le processus actuel.
Harry Johnston
0

J'aime utiliser ceci:

string e = Environment.Is64BitOperatingSystem

De cette façon, si j'ai besoin de localiser ou de vérifier un fichier, je peux facilement écrire:

string e = Environment.Is64BitOperatingSystem

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

       // Else 32 bit
       : @"C:\Program Files\";
user1351333
la source
13
qu'en est-il du processus 32 bits dans la machine OS 64 bits?
Kiquenet
3
Est-ce vraiment si difficile à utiliser Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)au lieu de coder en dur `C: \ Program Files`?
Luaan
2
Ne codez jamais en dur des "fichiers programme", car c'est une chaîne localisable. Αρχεία Εφαρμογών, Arquivos de Programas, etc.
stevieg