プログラムでJavaのオペレーティングシステムを確認するにはどうすればよいですか?


526

Javaプログラムがプログラムで実行しているホストのオペレーティングシステムを確認したい(たとえば、WindowsプラットフォームかUnixプラットフォームかに基づいて、さまざまなプロパティをロードできるようにしたい)。100%の信頼性でこれを行う最も安全な方法は何ですか?

回答:


617

以下を使用できます。

System.getProperty("os.name")

PSあなたはこのコードが役に立つかもしれません:

class ShowProperties {
    public static void main(String[] args) {
        System.getProperties().list(System.out);
    }
}

これは、Java実装によって提供されるすべてのプロパティを出力するだけです。プロパティを介してJava環境について何がわかるかがわかります。:-)


6
私は使用Windows 10していos.nameますが、それでもくれWindows 8.1ます。何故ですか?これはどこから来たのですか?
ブライアン



82

2008年10月:

静的変数にキャッシュすることをお勧めします。

public static final class OsUtils
{
   private static String OS = null;
   public static String getOsName()
   {
      if(OS == null) { OS = System.getProperty("os.name"); }
      return OS;
   }
   public static boolean isWindows()
   {
      return getOsName().startsWith("Windows");
   }

   public static boolean isUnix() // and so on
}

そうすれば、Osを要求するたびに、アプリケーションの存続期間中にプロパティを2回以上フェッチすることはありません。


2016年2月:7年以上後:

Windows 10にはバグがあります(元の回答の時点では存在していませんでした)。
Windows 10のJavaの「os.name」を参照してください


5
OAOOに基づいて(1回だけ)、getOSName関数に同意します。ただし、ハッシュ検索の速度を考えると、キャッシュは完全に冗長です。
Chris Jester-Young

6
完全に冗長なものは少し厳しいかもしれませんが、ハッシュ検索は参照にアクセスするよりも高価です。それはすべてコンテキストに依存します。
クレイグデイ

2
良い点...あなたがそれが悪い習慣だと思ったら自由に投票してください;)
VonC '23

5
私はこの答えを読み直しました。あなたがキャッシュしようとしている場合は、値のキャッシュisWindowsisUnixあなたはまた、文字列の比較時間を節約する方法ことなどを、。
Chris Jester-Young

2
@ブライアン・トゥルー。この非常に古い回答を適宜編集して、最新の回答を参照します。
VonC、2016

44

上記の回答の一部のリンクが壊れているようです。以下のコードに現在のソースコードへのポインターを追加し、結果としてenumを使用してチェックを処理する方法を提供し、結果を評価するときにswitchステートメントを使用できるようにします。

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

ヘルパークラスは次のとおりです。

/**
 * 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;
  }
}

3
(OS.indexOf( "darwin")> = 0)は(OS.indexOf( "win")> = 0)の後に来るため、真になることはありません
William

14
上記のコードは、ロケールに依存するtoLowerCase()を使用しているため、ロケールの問題がある可能性があります。これが問題になるのは、特にiを小文字/大文字に変換するときです。トルコでは、ドットなしの小文字のi(ı)になり、大文字のドット付きのi(İ)になります。したがって、 "WINDOWS" .toLowerCase()。indexOf( "win")はトルコでは-1を返します。特定の言語の小文字を実行するときは常にロケールを渡します。つまり、 "WINDOWS" .toLowerCase(Locale.ENGLISH).indexOf( "win")はトルコで機能します。
James Roper

@JamesRoper-ありがとう、これを修正しました。
Wolfgang Fahl 2014

7
OS.contains(...)
Grigory Kislin 2015年

42

次のJavaFXクラスには、現在のOS(isWindows()、isLinux()...)を判別するための静的メソッドがあります。

  • com.sun.javafx.PlatformUtil
  • com.sun.media.jfxmediaimpl.HostUtils
  • com.sun.javafx.util.Utils

例:

if (PlatformUtil.isWindows()){
           ...
}

これはもっと高いはずです
生息地

3
「com / sun / javafx / *」へのアクセスは現在推奨されていないことに注意してください(JDK 1.8.0_121でチェックされています)。
マイケルマートン2018年

1
@MichaelMartonステートメントのリファレンスをお持ちですか?
Hummeling Engineering BV 2018

@HummelingEngineeringBV:私の側からのミスだったと思います。私はEclipse Neon 4.6.3を使用していますが、「Javaビルドパス」にいくつかの「警告:com / sun / javafx / **」警告が表示されます。しかし、私が知ったように、これはたまたまEclipseのバグや機能です(リンクを参照)。
マイケルマートン2018

2
もう一度自分を直さなければならない。Java 9/10以降、いくつかの「com.sun。*」パッケージ/ APIが削除されようとしています。詳細については、このリンクを確認してください。これらのパッケージのいくつかを使用しているため、実際にこれにつまずきました。Eclipse 4.8 / JDK 10に移行すると、参照の欠落に起因するこれらおよびその他のいくつかのコンパイラエラーを修正する必要があります。
マイケルマートン2018

16

TL; DR

OSの使用にアクセスする場合: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;
    }
}

これで、次のように任意のクラスからクラスを簡単に呼び出すことができます(PSはos変数を静的として宣言しているため、システムタイプを識別するために一度だけ時間を消費し、アプリケーションが停止するまで使用できます)。

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

そして、それだけです!


2
このコードをオープンソースプロジェクト(github.com/openhab/openhab-addons)で使用したいのですが、大丈夫ですか?
Consti P

はい、お気軽にご利用ください。
Memin

13

あなたが達成しようとしていることの小さな例は、おそらくclass下にあるものに似ているでしょう:

import java.util.Locale;

public class OperatingSystem
{
    private static String OS = System.getProperty("os.name", "unknown").toLowerCase(Locale.ROOT);

    public static boolean isWindows()
    {
        return OS.contains("win");
    }

    public static boolean isMac()
    {
        return OS.contains("mac");
    }

    public static boolean isUnix()
    {
        return OS.contains("nux");
    }
}

この特定の実装は非常に信頼性が高く、普遍的に適用できるはずです。コピーして、おclass好みの場所に貼り付けてください。


10

オープンソースプロジェクトがこのような処理を行う方法に興味がある場合は、このジャンクを処理するTerracottaクラス(Os.java)をここで確認できます。

また、JVMバージョン(Vm.javaおよびVmVersion.java)を処理するための同様のクラスをここで確認できます。


2
そのテラコッタのクラスはかなり包括的です!
スチュワート

3
ライセンスに注意してください!!
harschware 2015

ウォルフガングファールの回答でジェームズローパーによって特定された同じ問題- toLowerCaseロケールを指定せずに使用
kbolino

9

これを試してください、シンプルで簡単です

System.getProperty("os.name");
System.getProperty("os.version");
System.getProperty("os.arch");

9

このプロジェクトから取得https://github.com/RishiGupta12/serial-communication-manager

String osName = System.getProperty("os.name");
String osNameMatch = osName.toLowerCase();
if(osNameMatch.contains("linux")) {
    osType = OS_LINUX;
}else if(osNameMatch.contains("windows")) {
    osType = OS_WINDOWS;
}else if(osNameMatch.contains("solaris") || osNameMatch.contains("sunos")) {
    osType = OS_SOLARIS;
}else if(osNameMatch.contains("mac os") || osNameMatch.contains("macos") || osNameMatch.contains("darwin")) {
    osType = OS_MAC_OS_X;
}else {
}

8

以下のコードは、システムAPIから取得できる値を示しています。これらは、このAPIを通じて取得できるすべてのものです。

public class App {
    public static void main( String[] args ) {
        //Operating system name
        System.out.println(System.getProperty("os.name"));

        //Operating system version
        System.out.println(System.getProperty("os.version"));

        //Path separator character used in java.class.path
        System.out.println(System.getProperty("path.separator"));

        //User working directory
        System.out.println(System.getProperty("user.dir"));

        //User home directory
        System.out.println(System.getProperty("user.home"));

        //User account name
        System.out.println(System.getProperty("user.name"));

        //Operating system architecture
        System.out.println(System.getProperty("os.arch"));

        //Sequence used by operating system to separate lines in text files
        System.out.println(System.getProperty("line.separator"));

        System.out.println(System.getProperty("java.version")); //JRE version number

        System.out.println(System.getProperty("java.vendor.url")); //JRE vendor URL

        System.out.println(System.getProperty("java.vendor")); //JRE vendor name

        System.out.println(System.getProperty("java.home")); //Installation directory for Java Runtime Environment (JRE)

        System.out.println(System.getProperty("java.class.path"));

        System.out.println(System.getProperty("file.separator"));
    }
}

回答:-

Windows 7
6.1
;
C:\Users\user\Documents\workspace-eclipse\JavaExample
C:\Users\user
user
amd64


1.7.0_71
http://java.oracle.com/
Oracle Corporation
C:\Program Files\Java\jre7
C:\Users\user\Documents\workspace-Eclipse\JavaExample\target\classes
\

7

SwingxOS Utilsがうまく機能していることがわかりました。


2
上記のリンクはおそらく壊れているようです、おそらくSwingXがブランチを導入したためです。1.6リリースはここにある:swingx.dev.java.net/source/browse/swingx/tags/SwingX-1-6/src/...
デヴィッド・モグラ

1
@David Moles、ありがとう。私が答えたとき、リンクは大丈夫でした-私はあなたのものでそれを更新しました。
Richard Harrison、




4

sun.awt.OSInfo#getOSType()メソッドだけを使用できます


これが最良の答えです。誰かがすでにここでこれについて言及しているかどうかを確認していました。
Martin KrajKraírovič18年

これに対する「制限されたAPI」の回避策はありますか?これを試してみたいのですが、Eclipseで警告が出ます。古いjre(例:jre1.8.0_171)を使用できますが、最新の1.8 jresは制限付きとしてマークされています。
Brian_Entei

4

セキュリティ上重要な環境で作業している場合は、これを最後までお読みください。

System#getProperty(String)サブルーチンで取得した物件は絶対に信用しないでください!実際、、、を含むほとんどすべてのプロパティはos.arch、期待どおりに読み取り専用os.nameos.versionはありません。代わりに、実際にはまったく逆です。

まず第一に、System#setProperty(String, String)サブルーチンを呼び出すのに十分な権限を持つコードは、返されたリテラルを自由に変更できます。それは、いわゆるを使用して解決できるようしかし、それは、ここでは必ずしも主な問題ではありませんSecurityManagerをより詳細に説明するように、ここに

実際の問題はJAR、問題のを実行するときに、すべてのユーザーがこれらのプロパティを編集できることです。つまり、これらのプロパティが実際に実際に正確であるかどうかを判断する方法はありません。このため、改ざんを回避するためのいくつかの追加チェックを次に示します。

// The first thing we're able to do is to query the filesystem.
switch (java.io.File.separator)
{
    case "/":
        // Windows is a potential candidate.
        break;
    case "\\":
        // And here it could really be anything else.
        break;
    default:
        // There's probably something really wrong here by now.
        break;
}

別の良いアイデアは、オペレーティングシステム固有のディレクトリの存在を確認することです。どのようなアプローチを取る場合でも、Java言語はクロスプラットフォームであることを示しています。だから、同じことをしてみませんか?


3

ヴォルフガングの答えが気に入ったのは、そのようなことがconstsである必要があると思っているからです...

だから私は自分のために少し言い換えて、それを共有しようと思いました:)

/**
 * types of Operating Systems
 *
 * please keep the note below as a pseudo-license
 *
 * helper class to check the operating system this Java VM runs in
 * 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
 */
public enum OSType {
    MacOS("mac", "darwin"),
    Windows("win"),
    Linux("nux"),
    Other("generic");

    private static OSType detectedOS;

    private final String[] keys;

    private OSType(String... keys) {
        this.keys = keys;
    }

    private boolean match(String osKey) {
        for (int i = 0; i < keys.length; i++) {
            if (osKey.indexOf(keys[i]) != -1)
                return true;
        }
        return false;
    }

    public static OSType getOS_Type() {
        if (detectedOS == null)
            detectedOS = getOperatingSystemType(System.getProperty("os.name", Other.keys[0]).toLowerCase());
        return detectedOS;
    }

    private static OSType getOperatingSystemType(String osKey) {
        for (OSType osType : values()) {
            if (osType.match(osKey))
                return osType;
        }
        return Other;
    }
}

「win」をチェックすると、すでにWindowsが返されるため、「darwin」を一致させることはできません。
tvkanters 14年

私の元の回答の修正を参照してください
Wolfgang Fahl 2014年

3
おめでとうございます。sun.awt.OSInfo#getOSType :)を再実装しました
Kirill Gamazkov

HHHHH ...いいね... @Kirill Gamazkov私はそれを見つけられなかった..指摘してくれてありがとう
TacB0sS '27

2

システムのOSタイプ、名前、Java情報などに関するすべての情報を表示するためのこのコード。

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Properties pro = System.getProperties();
    for(Object obj : pro.keySet()){
        System.out.println(" System  "+(String)obj+"     :  "+System.getProperty((String)obj));
    }
}

1

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)を見つけてクラスパスに追加します。


1

com.sun.javafx.util.Utils以下のように使用してください。

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

または使用

boolean isWindows = OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS);
       if (isWindows){
         // YOUR LOGIC HERE
       }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.