适用于 Windows 10 的 Java 的“os.name”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31909107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:45:13  来源:igfitidea点击:

Java's "os.name" for Windows 10?

javaoperating-systemjvmwindows-10getproperty

提问by BloodShura

In Java, we can see the property value of os.nameto know the name of the underlying operating system: System.getProperty("os.name").

在 Java 中,我们可以通过查看 的属性值os.name来了解底层操作系统的名称:System.getProperty("os.name").

For each edition of Windows, it used to return always the exact name of the OS: Windows XPfor XP, Windows Vistafor Vista, Windows 7for Seven, Windows 8.1for 8.1, and so on...

对于每个版本的 Windows,它过去总是返回操作系统的确切名称:Windows XP对于 XP、Windows Vista对于 Vista、Windows 7对于 7、Windows 8.1对于 8.1,等等......

The problem is: I just updated my Windows 8.1 to Windows 10 using the released Microsoft updater, and it seems like this property still remains Windows 8.1:

问题是:我刚刚使用已发布的 Microsoft 更新程序将我的 Windows 8.1 更新到了 Windows 10,并且这个属性似乎仍然存在Windows 8.1

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

How can I create a workaround for this? And, does anyone know if this problem persists if installing a fresh Windows 10 copy - that is, this bug is caused by the Microsoft auto-updater -?

如何为此创建解决方法?而且,有人知道如果安装新的 Windows 10 副本,这个问题是否仍然存在——也就是说,这个错误是由 Microsoft 自动更新程序引起的——?

采纳答案by apangin

This is a known problem JDK-8066504that has been fixed in upcoming Java 8 update 60.

这是一个已知问题JDK-8066504,已在即将发布的 Java 8 更新 60 中修复。

The reason is GetVersionExfunction has changed its behavior since Windows 8.1.

原因是GetVersionEx函数从 Windows 8.1 开始改变了它的行为。

There are multiple possible workarounds, see MSDN article.

有多种可能的解决方法,请参阅MSDN 文章

The trivial one is to exec cmd.exe /c ver.

微不足道的一个是 exec cmd.exe /c ver

The other is to look at the version information of one of the system files, e.g. kernel32.dll.

另一种是查看系统文件之一的版本信息,例如kernel32.dll.

回答by bpgeck

This is definitely a known bug. It occurs because the os.nameproperty gets its value from the GetVersionExin the source code of the Windows API. GetVersionExhowever,

这绝对是一个已知的错误。这是因为该os.name属性从GetVersionExWindows API 的源代码中获取其值。GetVersionEx然而,

may be altered or unavailable for releases after Windows 8.1

Windows 8.1 之后的版本可能会更改或不可用

As per Microsoft's official website. Instead, we will need to use the IsWindows10OrGreaterfound in the Version Helper API functions in the versionhelpers.hfile. As you probably guessed though, this file is not a Java file, it is written in C. As a result we need to include it in a somewhat roundabout way. It does take quite a bit of work (you need to program in JNI :/) but this tutorialwill help you do it. Another solution is shown in this bug log, and does require less effort.

根据微软官方网站。相反,我们需要使用IsWindows10OrGreaterversionhelpers.h文件中的 Version Helper API 函数中找到的。不过,您可能已经猜到了,这个文件不是 Java 文件,它是用 C 编写的。因此,我们需要以一种有点迂回的方式包含它。这确实需要相当多的工作(您需要在 JNI 中编程:/)但本教程将帮助您做到这一点。此错误日志中显示了另一种解决方案,并且确实需要较少的努力。

回答by s0urc3d3v3l0pm3nt

You could also use the .contains()method and just check for the "windows" string maybe along the lines of

您也可以使用该.contains()方法,只需检查“windows”字符串

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

If you need the windows version you could check for all versions and then assume 8.1 or 10 to move around the bug.

如果您需要 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

}

Now to explain what is going on here:

现在解释一下这里发生了什么:

  1. the if statement is just a conditional to determine the version of windows

  2. The System.getProperty("os.name")returns the name of the os as a string

  3. The .toLowerCase()method makes that returned String lower case

  4. The .contains(String)method checks if the given input string is contained in the String it is being called on

  5. The last statement allows for different code for each os except 8.1 & 10 which would need to be handled as one block :(

  1. if语句只是判断windows版本的条件

  2. System.getProperty("os.name")返回OS的名称作为一个字符串

  3. .toLowerCase()方法使返回的字符串小写

  4. .contains(String)方法检查给定的输入字符串是否包含在它被调用的字符串中

  5. 最后一条语句允许每个操作系统使用不同的代码,除了 8.1 和 10 需要作为一个块处理:(

回答by WesternGun

Hm... I don't know if it is a fix of Windows 10(10.0.17134.590) or of Java 8(1.8.0_171-b11for me), but it is correct now: os.namegives me Windows 10.

嗯...我不知道它是 Windows 10( 10.0.17134.590) 还是 Java 8(1.8.0_171-b11对我来说)的修复,但现在是正确的:os.name给我Windows 10.

Besides, if you don't trust it, you can check os.version. I have 10.0.

此外,如果您不信任它,您可以检查os.version. 我有10.0

(By the way, I see os.arch:amd64. This is of JVM, not of OS. )

(顺便说一下,我明白了os.arch:amd64。这是 JVM,而不是 OS。)

回答by Devashish Saksena

I faced the same issue, used the following workaround: The cmd command "systeminfo" returns "OS Name:" which is the right name for the OS, wrote the following function for this:

我遇到了同样的问题,使用了以下解决方法: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;
}