我想确定我的Java程序以编程方式运行的主机的操作系统(例如:我希望能够根据我是在Windows还是Unix平台上加载不同的属性)。100%可靠的最安全的方法是什么?


当前回答

如果您正在安全敏感的环境中工作,那么请通读本文。

请不要相信通过system# getProperty(String)子例程获得的属性!实际上,几乎所有的属性包括os。Arch, os.name和os.name。版本并不是你所期望的只读的——相反,它们实际上恰恰相反。

首先,任何具有调用system# setProperty(String, String)子例程足够权限的代码都可以随意修改返回的文字。然而,这并不一定是这里的主要问题,因为它可以通过使用所谓的SecurityManager来解决,如这里更详细的描述。

实际的问题是,任何用户都可以在运行JAR时编辑这些属性(通过-Dos.name=, -Dos.name=, -Dos.name=)。拱=,等等)。避免篡改应用程序参数的一种可能方法是查询RuntimeMXBean,如下所示。下面的代码片段应该提供一些关于如何实现这一点的见解。

RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();

for (String argument : arguments) {
    if (argument.startsWith("-Dos.name") {
        // System.getProperty("os.name") altered
    } else if (argument.startsWith("-Dos.arch") {
        // System.getProperty("os.arch") altered
    }
}

其他回答

在com.sun.jna.Platform类中,您可以找到有用的静态方法,例如

Platform.isWindows();
Platform.is64Bit();
Platform.isIntel();
Platform.isARM();

还有更多。

如果使用Maven,只需添加依赖项

<dependency>
 <groupId>net.java.dev.jna</groupId>
 <artifactId>jna</artifactId>
 <version>5.2.0</version>
</dependency>

否则,只需找到jna库jar文件(例如jna-5.2.0.jar)并将其添加到类路径。

只需使用下面的com.sun.javafx.util.Utils即可。

if ( Utils.isWindows()){
     // LOGIC HERE
}

或使用

boolean isWindows = OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS);
       if (isWindows){
         // YOUR LOGIC HERE
       }

博士TL;

访问操作系统使用:System.getProperty(" OS .name")。


但是等等! !

为什么不创建一个实用工具类,使其可重用!而且在多次通话中可能会更快。干净,清晰,快点!

为这样的实用函数创建一个Util类。然后为每种操作系统类型创建公共枚举。

public class Util {     
        public enum OS {
            WINDOWS, LINUX, MAC, SOLARIS
        };// Operating systems.

    private static OS os = null;

    public static OS getOS() {
        if (os == null) {
            String operSys = System.getProperty("os.name").toLowerCase();
            if (operSys.contains("win")) {
                os = OS.WINDOWS;
            } else if (operSys.contains("nix") || operSys.contains("nux")
                    || operSys.contains("aix")) {
                os = OS.LINUX;
            } else if (operSys.contains("mac")) {
                os = OS.MAC;
            } else if (operSys.contains("sunos")) {
                os = OS.SOLARIS;
            }
        }
        return os;
    }
}

现在,您可以轻松地从任何类中调用类,如下所示由于我们将os变量声明为静态,它只会花费一次时间来识别系统类型,然后它可以一直使用到应用程序停止。)

            switch (Util.getOS()) {
            case WINDOWS:
                //do windows stuff
                break;
            case LINUX:

就是这样!

上面答案中的一些链接似乎被打破了。我在下面的代码中添加了指向当前源代码的指针,并提供了一种方法来处理以enum作为答案的检查,以便在计算结果时使用switch语句:

OsCheck.OSType ostype=OsCheck.getOperatingSystemType();
switch (ostype) {
    case Windows: break;
    case MacOS: break;
    case Linux: break;
    case Other: break;
}

helper类是:

/**
 * helper class to check the operating system this Java VM runs in
 *
 * please keep the notes below as a pseudo-license
 *
 * http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java
 * compare to http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/Os.java
 * http://www.docjar.com/html/api/org/apache/commons/lang/SystemUtils.java.html
 */
import java.util.Locale;
public static final class OsCheck {
  /**
   * types of Operating Systems
   */
  public enum OSType {
    Windows, MacOS, Linux, Other
  };

  // cached result of OS detection
  protected static OSType detectedOS;

  /**
   * detect the operating system from the os.name System property and cache
   * the result
   * 
   * @returns - the operating system detected
   */
  public static OSType getOperatingSystemType() {
    if (detectedOS == null) {
      String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
      if ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)) {
        detectedOS = OSType.MacOS;
      } else if (OS.indexOf("win") >= 0) {
        detectedOS = OSType.Windows;
      } else if (OS.indexOf("nux") >= 0) {
        detectedOS = OSType.Linux;
      } else {
        detectedOS = OSType.Other;
      }
    }
    return detectedOS;
  }
}

我认为下面的内容可以用更少的字里行间覆盖更广的范围

import org.apache.commons.exec.OS;

if (OS.isFamilyWindows()){
                //load some property
            }
else if (OS.isFamilyUnix()){
                //load some other property
            }

更多详情请访问:https://commons.apache.org/proper/commons-exec/apidocs/org/apache/commons/exec/OS.html