web-dev-qa-db-de.com

Wie bestimmen Sie die 32- oder 64-Bit-Architektur von Windows mithilfe von Java?

Wie bestimmen Sie die 32- oder 64-Bit-Architektur von Windows mithilfe von Java?

53
Matthew

Bitte beachten Sie, dass die os.Arch-Eigenschaft nur die Architektur von JRE angibt, nicht des zugrunde liegenden Betriebssystems. 

Wenn Sie eine 32-Bit-Version auf einem 64-Bit-System installieren, gibt System.getProperty("os.Arch")x86 zurück.

Um die zugrunde liegende Architektur tatsächlich bestimmen zu können, müssen Sie nativen Code schreiben. Siehe diesen Beitrag für weitere Informationen (und einen Link zum nativen Beispielcode)

54
James Van Huis

Ich vertraue nicht genau auf die Systemvariable os.Arch. Es funktioniert zwar, wenn ein Benutzer eine 64-Bit-JVM auf einem 64-Bit-System ausführt. Es funktioniert nicht, wenn der Benutzer eine 32-Bit-JVM auf einem 64-Bit-System ausführt.

Mit dem folgenden Code können Sie Windows-64-Bit-Betriebssysteme richtig erkennen. Bei einem Windows 64-Bit-System wird die Umgebungsvariable "Programfiles (x86)" festgelegt. Es wird NICHT auf einem 32-Bit-System gesetzt und Java liest es als Null.

boolean is64bit = false;
if (System.getProperty("os.name").contains("Windows")) {
    is64bit = (System.getenv("ProgramFiles(x86)") != null);
} else {
    is64bit = (System.getProperty("os.Arch").indexOf("64") != -1);
}

Bei anderen Betriebssystemen wie Linux, Solaris oder Mac kann dieses Problem ebenfalls auftreten. Das ist also keine vollständige Lösung. Für Mac sind Sie wahrscheinlich sicher, da Apple die JVM an das Betriebssystem anpasst. Linux, Solaris usw. verwenden sie jedoch möglicherweise immer noch eine 32-Bit-JVM auf ihrem 64-Bit-System. Verwenden Sie dies daher mit Vorsicht.

72
Boolean

Ich habe den Befehl Prompt (Befehl -> wmic OS get OSArchitecture) verwendet, um die Betriebssystemarchitektur abzurufen. Das folgende Programm hilft dabei, alle erforderlichen Parameter zu erhalten:

import Java.io.*;

public class User {
    public static void main(String[] args) throws Exception {

        System.out.println("OS --> "+System.getProperty("os.name"));   //OS Name such as Windows/Linux

        System.out.println("JRE Architecture --> "+System.getProperty("Sun.Arch.data.model")+" bit.");       // JRE architecture i.e 64 bit or 32 bit JRE

        ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c","wmic OS get OSArchitecture");
        builder.redirectErrorStream(true);
        Process p = builder.start();
        String result = getStringFromInputStream(p.getInputStream());

        if(result.contains("64"))
            System.out.println("OS Architecture --> is 64 bit");  //The OS Architecture
        else
            System.out.println("OS Architecture --> is 32 bit");

        }


    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }

}
5
Crusaderpyro

(Nur für Windows) Überprüfen Sie, ob C:\Windows\SysWOW64 Existiert . Wenn das Verzeichnis vorhanden ist, handelt es sich um einen 64-Bit-Prozess.

0
Olligaming1107

Vielleicht ist es nicht der beste Weg, aber es funktioniert. 

Ich brauche nur die "Umgebungsvariable", die Windows für den Ordner "Programme x86" konfiguriert hat. Ich meine, Windows x64 habe den Ordner (Programme x86) und der x86 nicht. Da ein Benutzer den Pfad der Programmdateien in Enviroment Variables ändern kann oder ein Verzeichnis "Programme (x86)" in C:\erstellen kann, verwende ich nicht die Erkennung des Ordners, sondern den "Umgebungspfad" des Programms Dateien (x86) "mit der Variablen in der Windows-Registrierung.

public class getSystemInfo {

    static void suckOsInfo(){

    // Get OS Name (Like: Windows 7, Windows 8, Windows XP, etc.)
    String osVersion = System.getProperty("os.name");
    System.out.print(osVersion);

    String pFilesX86 = System.getenv("ProgramFiles(X86)");
    if (pFilesX86 !=(null)){
        // Put here the code to execute when Windows x64 are Detected
    System.out.println(" 64bit");
    }
    else{
        // Put here the code to execute when Windows x32 are Detected
    System.out.println(" 32bit");
    }

    System.out.println("Now getSystemInfo class will EXIT");
    System.exit(0);

    }

}
0
Blackgeo32

Haftungsausschluss: Bitte stimmen Sie das nicht als doppelte Antwort ab, da ich meine Java-Codelösung dazu freigeben wollte (die eine ist ein nativer Code).

Ich möchte die Antwort von Herrn James Van Huis zusammenfassen: Da die Eigenschaft os.Arch: System.getProperty("os.Arch"); Die Bitness von JRE zurückgibt, kann dies tatsächlich sehr nützlich sein . Aus dem Artikel: 

In Ihrem Code müssen Sie zunächst die Größe von IntPtr überprüfen. Wenn 8 zurückgegeben wird, laufen Sie auf einem 64-Bit-Betriebssystem. Wenn 4 zurückgegeben wird, führen Sie eine 32-Bit-Anwendung aus. Nun müssen Sie wissen, ob Sie nativ oder unter WOW64 ausgeführt werden.

Daher ist die IntPtr-Größenprüfung die gleiche Prüfung, die Sie in "os.Arch" durchführen. Danach können Sie herausfinden, ob der Prozess nativ oder unter WOW64 ausgeführt wird.

Dies kann mithilfe der jna-Bibliothek (z. B. NativeLibrary ) erfolgen, die die Verwendung der von Ihnen benötigten nativen Funktionen bietet.

//test the JRE here by checking the os.Arch property
//go into the try block if JRE is 32bit
try {
    NativeLibrary kernel32Library = NativeLibrary.getInstance("kernel32");
    Function isWow64Function = kernel32Library.getFunction("IsWow64Process");

    WinNT.HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess();
    IntByReference isWow64 = new IntByReference(0);
    Boolean returnType = false;
    Object[] inArgs = {
        hProcess,
        isWow64
    };
    if ((Boolean) isWow64Function.invoke(returnType.getClass(), inArgs))    {
        if (isWow64.getValue() == 1)    {
                //32bit JRE on x64OS
        }
    }
} catch (UnsatisfiedLinkError e) {  //thrown by getFunction

}

So etwas könnte auch funktionieren, aber ich würde die erste Version empfehlen, da ich sie auf x64 und 32bit JRE unter x64 OS getestet habe. Es sollte auch der sicherere Weg sein, da Sie im Folgenden nicht wirklich prüfen, ob die Funktion "IsWow64Process" vorhanden ist.

Hier füge ich ein Beispiel für den JRE-Check hinzu, nur damit er vollständig ist, auch wenn er nicht schwer zu finden ist.

Map<String, Integer> archMap = new HashMap<String, Integer>();
archMap.put("x86", 32);
archMap.put("i386", 32);
archMap.put("i486", 32);
archMap.put("i586", 32);
archMap.put("i686", 32);
archMap.put("x86_64", 64);
archMap.put("AMD64", 64);
//archMap.put("powerpc", 3);
this.Arch = archMap.get(SystemUtils.OS_Arch);
if (this.Arch == null)  {
    throw new IllegalArgumentException("Unknown architecture " + SystemUtils.OS_Arch);
}
0
wckan_

Sie können diesen Code ausprobieren. Ich denke, es ist besser, das Modell der JVM zu erkennen

boolean is64bit = System.getProperty("Sun.Arch.data.model").contains("64");
0
user2181778