So bestimmen Sie programmgesteuert, ob ein bestimmter Prozess 32-Bit oder 64-Bit ist

102

Wie kann meine C # -Anwendung prüfen, ob eine bestimmte Anwendung / ein bestimmter Prozess (Hinweis: nicht der aktuelle Prozess) im 32-Bit- oder 64-Bit-Modus ausgeführt wird?

Beispielsweise möchte ich möglicherweise einen bestimmten Prozess nach seinem Namen abfragen, z. B. 'abc.exe', oder basierend auf der Prozess-ID-Nummer.

Satya
quelle
Bitte geben Sie die Sprache immer als Tag ein. Ich werde das jetzt in diesem Beitrag ändern. :-)
Dean J
3
Bitte klären Sie, ob Sie wissen möchten, dass der aktuelle Prozess 64-Bit ist, oder ob Sie einen anderen Prozess abfragen.
Mehrdad Afshari
Dupelicate: stackoverflow.com/questions/266082/…
Lawrence Johnston

Antworten:

177

Eine der interessanteren Möglichkeiten, die ich gesehen habe, ist folgende:

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

Verwenden Sie diesen Code, um herauszufinden, ob ANDERE Prozesse im 64-Bit-Emulator (WOW64) ausgeführt werden:

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
quelle
8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) Und deshalb muss Microsoft Kompatibilitäts-Shims für Versionslügen erstellen, um solche Fehler im Code zu umgehen. Was passiert, wenn Windows Vista (6.0) herauskommt? Und die Leute haben Microsoft schlecht gemacht, weil sie Windows 7 Version 6.1 statt 7.0 erstellt haben. Es behebt so viele App-kompatible Fehler.
Ian Boyd
4
Der Funktionsname IsWin64 ist meiner Meinung nach etwas irreführend. Es gibt true zurück, wenn der 32-Bit-Prozess unter x64 ausgeführt wird.
Denis The Menace
2
Warum processHandle = Process.GetProcessById(process.Id).Handle;statt nur verwenden processHandle = process.Handle;?
Jonathon Reinhart
1
@ JonathonReinhart gut ist das nicht nur eine gute Frage. Ich habe keine Ahnung. Es muss ein Überbleibsel von einem Umschalten gewesen sein, Dinge auf die eine oder andere Weise zu tun. Danke, dass du das gefunden hast!
Jesse C. Slicer
1
Diese Antwort ist einfach falsch; und die Rückgabe von false, anstatt im Fehlerfall eine Ausnahme auszulösen, ist ein sehr schlechtes Design.
user626528
141

Wenn Sie .Net 4.0 verwenden, ist dies ein Einzeiler für den aktuellen Prozess:

Environment.Is64BitProcess

Siehe Environment.Is64BitProcessProperty (MSDN).

Sam
quelle
2
Könnten Sie den Code von posten Is64BitProcess? Vielleicht kann ich damit herausfinden, ob ich als 64-Bit-Prozess arbeite.
Ian Boyd
1
@ Ian, ich bezweifle, dass Sam gesetzlich berechtigt ist, MS-Code in diesem Forum zu veröffentlichen. Ich bin mir nicht sicher über den genauen Inhalt ihrer Referenzlizenz, aber ich bin mir ziemlich sicher, dass sie die Reproduktion des Codes überall verbietet.
ProfK
3
@ Ian jemand hat diese Arbeit für Sie erledigt
Robert MacLean
4
Das OP hat ausdrücklich darum gebeten, einen anderen Prozess abzufragen , nicht den aktuellen Prozess.
Harry Johnston
1
Beachten Sie, dass Microsoft hat den Code für Post Is64BitProcess( referencesource.microsoft.com/#mscorlib/system/environment.cs ). Es handelt sich jedoch nur um eine fest codierte return-Anweisung, die vom Kompilierungssymbol gesteuert wird.
Brian
20

Die ausgewählte Antwort ist falsch, da sie nicht das tut, was gefragt wurde. Es wird geprüft, ob es sich bei einem Prozess um einen x86-Prozess handelt, der stattdessen unter x64 ausgeführt wird. Daher wird "false" für einen x64-Prozess unter x64-Betriebssystem oder einen x86-Prozess unter x86-Betriebssystem zurückgegeben.
Außerdem werden Fehler nicht richtig behandelt.

Hier ist eine korrektere Methode:

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
quelle
1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"wird für einen 32-Bit-Prozess immer true zurückgeben. Besser zu verwenden, System.Environment.Is64BitOperatingSystemwenn .NET4 unterstützt wird
Aizzat Suhardi
10

Sie können die Größe eines Zeigers überprüfen, um festzustellen, ob er 32 oder 64 Bit hat.

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();
Darwyn
quelle
6
Zum Zeitpunkt der ersten Veröffentlichung dieser Antwort war dies nicht sehr klar, aber das OP wollte wissen, wie ein anderer Prozess anstelle des aktuellen Prozesses abgefragt werden kann.
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
quelle
5
Das OP fragte speziell, wie ein anderer Prozess abgefragt werden soll, nicht der aktuelle Prozess.
Harry Johnston
1

Hier ist die einzeilige Prüfung.

bool is64Bit = IntPtr.Size == 8;
Vikram Bose
quelle
6
Das OP fragte speziell, wie ein anderer Prozess abgefragt werden soll, nicht der aktuelle Prozess.
Harry Johnston
0

Ich benutze dies gerne:

string e = Environment.Is64BitOperatingSystem

Auf diese Weise kann ich leicht schreiben, wenn ich eine Datei suchen oder überprüfen muss:

string e = Environment.Is64BitOperatingSystem

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

       // Else 32 bit
       : @"C:\Program Files\";
user1351333
quelle
13
Was ist mit 32-Bit-Prozess in 64-Bit-OS-Maschine?
Kiquenet
3
Ist es wirklich so schwer zu verwenden, Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)anstatt "C: \ Programme" fest zu codieren?
Luaan
2
Niemals "Programmdateien" fest codieren, da es sich um eine lokalisierbare Zeichenfolge handelt. Αρχεία Εφαρμογών, Arquivos de Programas usw.
stevieg