Java "os.name" для Windows 10?

В Java мы можем узнать значение свойства os.name, чтобы узнать имя базовой операционной системы: System.getProperty("os.name").

Для каждой редакции Windows она всегда возвращала точное имя ОС: Windows XP для XP, Windows Vista для Vista, Windows 7 для семи, Windows 8.1 для 8.1 и т.д..

Проблема в том, что я только что обновил свою Windows 8.1 до Windows 10 с помощью выпущенного обновления Microsoft, и похоже, что это свойство все еще остается Windows 8.1:

public class OSTest {
  public static void main(String[] args) {
    System.out.println(System.getProperty("os.name"));
  }
}

Как я могу создать обходной путь для этого? И кто-нибудь знает, сохраняется ли эта проблема при установке новой копии Windows 10, то есть эта ошибка вызвана автоматическим обновлением Microsoft -?

Ответ 1

Это известная проблема JDK-8066504, которая была исправлена ​​в предстоящем обновлении 60 Java.

Причина GetVersionEx изменила свое поведение с Windows 8.1.

Существует несколько возможных обходных решений, см. статью MSDN.

Тривиальным является exec cmd.exe /c ver.

Другим является просмотр информации о версии одного из системных файлов, например. kernel32.dll.

Ответ 2

Это определенно известная ошибка. Это происходит потому, что свойство os.name получает свое значение от GetVersionEx в исходном коде Windows API. GetVersionEx однако

может быть изменен или недоступен для выпусков после Windows 8.1

Согласно официальному сайту Microsoft. Вместо этого нам нужно будет использовать IsWindows10OrGreater, найденный в функциях API Версии Версии в файле versionhelpers.h. Как вы, наверное, догадались, этот файл не является файлом Java, он написан на C. В результате нам нужно включить его несколько обходным путем. Это займет довольно много работы (вам нужно программировать в JNI:/), но этот учебник поможет вам это сделать. Другое решение показано в этом журнале ошибок и требует меньше усилий.

Ответ 3

Я столкнулся с той же проблемой, использовал следующий обходной путь: Команда cmd "systeminfo" возвращает "Имя ОС:", которое является правильным именем для ОС, написал следующую функцию для этого:

private boolean os2k10Check()
{
try{

    Process p = Runtime.getRuntime().exec("systeminfo");        /*Execute cmd command "systeminfo"*/
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while (true) 
    {
        line = r.readLine();
        if (line == null) { break; }
        if(line.contains("OS Name:"))               /*If output contains OS Name and 2010*/
        {
        if(line.contains("2010"))
                return true;
        else
                return false;       
        }
    }
}
catch(Exception e)
    {System.out.println("Platform Type: os2010check: exception"+e);}

return false;
}

Ответ 4

Хм... Я не знаю, исправлено ли это для Windows 10 (10.0.17134.590) или Java 8 (для меня 1.8.0_171-b11), но сейчас это правильно: os.name дает мне Windows 10.

Кроме того, если вы не доверяете этому, вы можете проверить os.version. У меня 10.0.

(Кстати, я вижу os.arch:amd64. Это из JVM, а не из ОС.)

Ответ 5

Вы также можете использовать метод .contains() и просто проверить наличие "окон" строка может быть вдоль строк

if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains(windows version here [xp, 7, 8, etc]))){}

Если вам нужна версия Windows, вы можете проверить все версии, а затем считать, что 8.1 или 10 для перемещения по ошибке.

if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("xp")){
//code for windows xp }

else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("vista")){
//code for windows vista

else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("7")){
//code for windows 7}

else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("8")){
//code for windows 8}
else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("8.1")){
//code for both windows 8.1 and 10

}

Теперь, чтобы объяснить, что здесь происходит:

  • оператор if является условным только для определения версии Windows

  • System.getProperty("os.name") возвращает имя os в виде строки

  • Метод .toLowerCase() делает возвращаемый строковый нижний регистр

  • Метод .contains(String) проверяет, содержится ли данная строка ввода в строке, которую она вызывается в

  • Последний оператор допускает разный код для каждого os, кроме 8.1 и 10, который нужно будет обрабатывать как один блок: (