Как вы определяете 32 или 64-битную архитектуру Windows, используя Java? - PullRequest
54 голосов
/ 06 декабря 2009

Как вы определяете 32- или 64-битную архитектуру Windows, используя Java?

Ответы [ 9 ]

72 голосов
/ 16 февраля 2010

Я не совсем доверяю чтению системной переменной os.arch. Хотя это работает, если пользователь использует 64-битную JVM в 64-битной системе. Он не работает, если пользователь запускает 32-битную JVM в 64-битной системе.

Следующий код работает для правильного определения 64-разрядных операционных систем Windows. В 64-битной системе Windows переменная среды «Programfiles (x86)» будет установлен. Он НЕ будет установлен в 32-битной системе, и java будет читать его как ноль.

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

Для других операционных систем, таких как Linux, Solaris или Mac, мы также можем увидеть эту проблему. Так что это не полное решение. Для Mac вы, вероятно, в безопасности, потому что apple блокирует JVM в соответствии с ОС. Но Linux, Solaris и т. Д. Могут использовать 32-разрядную JVM в своей 64-разрядной системе. Так что используйте это с осторожностью.

54 голосов
/ 21 января 2010

Обратите внимание, что свойство os.arch даст вам только архитектуру JRE , а не лежащую в ее основе ОС.

Если вы установите 32-битную JRE в 64-битной системе, System.getProperty("os.arch") вернет x86

Чтобы на самом деле определить базовую архитектуру, вам нужно написать собственный код. См. этот пост для получения дополнительной информации (и ссылки на образец нативного кода)

5 голосов
/ 14 июля 2014

Я использовал командную строку (команда -> wmic OS get OSArchitecture), чтобы получить архитектуру ОС. Следующая программа помогает получить все необходимые параметры:

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

    }

}
2 голосов
/ 23 февраля 2018

Отказ от ответственности: пожалуйста, не отрицайте это как дубликат ответа, так как я хотел бы поделиться своим решением Java-кода с этим (один похож на нативный код).

Я хотел бы добавить к ответу мистера Джеймса Ван Хьюиса; Так как собственность os.arch: System.getProperty("os.arch"); возвращает битность JRE, это может быть очень полезно. Из статьи:

В вашем коде сначала нужно проверить размер IntPtr, если он возвращает 8, значит, вы работаете в 64-битной ОС. Если он вернет 4, значит, вы работаете с 32-битным приложением, поэтому теперь вам нужно знать, работаете ли вы в нём или под WOW64.

Следовательно, проверка размера IntPtr - это та же проверка, которую вы выполняете, просматривая «os.arch». После этого вы можете приступить к выяснению, работает ли процесс изначально или под WOW64.

Это можно сделать с помощью библиотеки jna (например, NativeLibrary ), которая предлагает использование необходимых вам нативных функций.

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

}

Нечто подобное может также работать, но я бы порекомендовал первую версию, поскольку она была протестирована на x64 и 32-битной JRE на x64 OS. Также это должно быть более безопасным способом, потому что в следующем вы фактически не проверяете, существует ли функция «IsWow64Process».

Здесь я добавляю пример проверки JRE, чтобы она была завершена, хотя ее не сложно найти.

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);
}
1 голос
/ 18 ноября 2017

(только для Windows) Проверьте, если C: \ Windows \ SysWOW64 существует. если каталог существует, это 64-битный процесс. Иначе, это 32-битный процесс.

1 голос
/ 18 марта 2013

Вы можете попробовать этот код, я думаю, что лучше определить модель JVM

boolean is64bit = System.getProperty("sun.arch.data.model").contains("64");
0 голосов
/ 16 октября 2013

Может быть, это не самый лучший способ, но он работает.

Все, что я делаю, это получаю «Переменную окружения», которую Windows настроил для папки Program Files x86. Я имею в виду, что у Windows x64 есть папка (Program Files x86), а у x86 нет. Поскольку пользователь может изменить путь к программным файлам в Enviroment Variables, или он / она может создать каталог «Program Files (x86)» в C: \, я не буду использовать обнаружение папки, но «Путь к среде» «Program Files (x86)» с переменной в реестре Windows.

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 голосов
/ 06 декабря 2009

Вы можете использовать свойство os.arch в системных свойствах, чтобы выяснить это.

Properties pr = System.getProperties();
System.out.println(pr.getProperty("os.arch"));

Если вы используете 32-разрядную версию, на ней должен отображаться i386 или что-то еще

0 голосов
/ 06 декабря 2009
System.getProperty("os.arch");
...