web-dev-qa-db-fra.com

Comment déterminer par programme le système d'exploitation en Java?

Je souhaite déterminer le système d'exploitation de l'hôte sur lequel mon programme Java s'exécute par programme (par exemple: je souhaite pouvoir charger différentes propriétés en fonction de ma plate-forme Windows ou Unix) . Quel est le moyen le plus sûr de le faire avec une fiabilité à 100%?

475
karlgrz

Vous pouvez utiliser:

System.getProperty("os.name")

P.S. Vous pouvez trouver ce code utile:

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

Tout ce qu’il fait est d’afficher toutes les propriétés fournies par vos implémentations Java. Cela vous donnera une idée de ce que vous pouvez trouver sur votre environnement Java via les propriétés. :-)

577
Chris Jester-Young

Comme indiqué dans d'autres réponses, System.getProperty fournit les données brutes. Cependant, le composant Apache Commons Lang fournit un wrapper pour Java.lang.System avec des propriétés pratiques comme SystemUtils.IS_OS_WINDOWS , un peu comme le Swingx OS util.

136
Leif Carlsen

Octobre 2008:

Je recommanderais de le mettre en cache dans une variable statique:

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
}

Ainsi, chaque fois que vous demandez le système d'exploitation, vous ne récupérez pas la propriété plus d'une fois dans la durée de vie de votre application.


Février 2016: 7 ans et plus après:

Il y a un bug avec Windows 10 (qui n'existait pas au moment de la réponse d'origine).
Voir " “ os.name ”de Java pour Windows 10? "

76
VonC

certains des liens dans les réponses ci-dessus semblent être cassés. J'ai ajouté des pointeurs au code source actuel dans le code ci-dessous et propose une approche permettant de gérer le contrôle avec une enum comme réponse, de sorte qu'une instruction switch puisse être utilisée lors de l'évaluation du résultat:

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

La classe d'assistance est:

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

Les classes JavaFX suivantes ont des méthodes statiques pour déterminer le système d'exploitation actuel (isWindows (), isLinux () ...):

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

Exemple:

if (PlatformUtil.isWindows()){
           ...
}
36
Igor Rybak
    private static String OS = System.getProperty("os.name").toLowerCase();

    public static void detectOS() {
        if (isWindows()) {

        } else if (isMac()) {

        } else if (isUnix()) {

        } else {

        }
    }

    private static boolean isWindows() {
        return (OS.indexOf("win") >= 0);
    }

    private static boolean isMac() {
        return (OS.indexOf("mac") >= 0);
    }

    private static boolean isUnix() {
        return (OS.indexOf("nux") >= 0);
    }
12
Nikesh Jauhari

Oui, la réponse courte est d'utiliser System.getProperty("os.name"). Mais pourquoi ne pas créer une classe d’utilité, la rendre réutilisable! Et probablement beaucoup plus rapidement sur plusieurs appels. Propre, clair, plus vite!

Créez une classe Util pour de telles fonctions utilitaires. Créez ensuite des énumérations publiques pour chaque type de système d'exploitation.

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

Maintenant, vous pouvez facilement appeler une classe à partir de n’importe quelle classe, comme suit (P.S. Comme nous avons déclaré la variable système comme statique, le temps nécessaire à l’identification du type de système ne sera consommé qu’une fois, puis il pourra être utilisé jusqu’à l’arrêt de votre application.)

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

et ça y est!

12
Memin

Si vous êtes intéressé par la façon dont un projet open source fait ce genre de choses, vous pouvez consulter la classe Terracotta (Os.Java) qui gère cette ordure ici:

Et vous pouvez voir une classe similaire pour gérer les versions de JVM (Vm.Java et VmVersion.Java) ici:

10
Alex Miller

Tiré de ce projet 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 {
}
9
john miller

Essayez ceci, simple et facile

System.getProperty("os.name");
System.getProperty("os.version");
System.getProperty("os.Arch");
8
Kamidu

Le code ci-dessous montre les valeurs que vous pouvez obtenir à partir de l'API système, tout ce que vous pouvez obtenir via cette 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"));
    }
}

Réponses:-

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
PAA

Je trouve que le OS Utils de Swingx fait le travail.

7
Richard Harrison

Je pense que la suite peut donner une couverture plus large en moins de lignes

import org.Apache.commons.exec.OS;

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

Plus de détails ici: https://commons.Apache.org/proper/commons-exec/apidocs/org/Apache/commons/exec/OS.html

6
Nafeez Quraishi
String osName = System.getProperty("os.name");
System.out.println("Operating system " + osName);
5
Vishal Chaudhari

J'ai aimé la réponse de Wolfgang, simplement parce que je crois que des choses comme ça devraient être constantes ...

alors je l'ai reformulé un peu pour moi et j'ai pensé à le partager :)

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

Vous pouvez simplement utiliser la méthode Sun.awt.OSInfo # getOSType ()

3
Kirill Gamazkov

Ce code permet d'afficher toutes les informations sur le type de système d'exploitation, le nom, les informations Java, etc.

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

Toutes les réponses ci-dessus sont sujettes à une faille fatale dans la conception du sous-programme System#getProperty!

Ne faites jamais jamais confiance aux propriétés os.name, os.version et os.Arch. En réalité, ces propriétés ne sont pas en lecture seule comme on pourrait s'y attendre. Au lieu de cela, un attaquant peut facilement y injecter un littéral de chaîne arbitraire!

Par exemple, sur mon ordinateur Windows 10 , le code ci-dessous affichera le littéral de chaîne "Linux". en suivant ces étapes:

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

Maintenant, après avoir compressé la class dans un exécutable JAR, nous pouvons en fait aller de l'avant et l'exécuter comme indiqué ci-dessous.

$ Java -jar PATH.jar -Dos.name = "Linux"

Ainsi, toutes les réponses ci-dessus pourraient exposer votre programme à penser qu'il s'exécute sur un tout faux OS. Vous pourriez vous demander maintenant comment on s'y prend pour résoudre ce problème? Pour l’instant, le seul moyen de remédier à cet oubli est de vérifier manuellement les paramètres de JVM au moment de l’exécution.

Voici un exemple de requête d'interrogation par programme de ces propriétés. Supposons que vous ajoutiez un bloc d'initialisation static à votre class primaire. Ensuite, le code suivant empêcherait quiconque de modifier de manière externe la propriété os.name.

if (Java.util.Arrays.toString(jdk.internal.misc.VM.getRuntimeArguments()).contains("Dos.name"))
{
    throw new Java.lang.InternalError("Please refrain from tampering with the \"os.name\" property.");
}

Le jdk.internal.misc.VMclass n'est pas destiné à être utilisé par public. Par conséquent, vous ne devriez pas l'utiliser dans le code de production!

2
Niklas Simandi

Dans la classe com.Sun.jna.Platform, vous pouvez trouver des méthodes statiques utiles telles que

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

et beaucoup plus.

Si vous utilisez Maven, ajoutez simplement une dépendance

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

Sinon, il suffit de trouver le fichier jar de la bibliothèque jna (par exemple, jna-5.2.0.jar) et de l'ajouter à classpath.

1

Utilisez simplement com.Sun.javafx.util.Utils comme ci-dessous.

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

OU UTILISATION

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