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%?
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. :-)
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.
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? "
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;
}
}
Les classes JavaFX suivantes ont des méthodes statiques pour déterminer le système d'exploitation actuel (isWindows (), isLinux () ...):
Exemple:
if (PlatformUtil.isWindows()){
...
}
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);
}
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!
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:
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 {
}
Essayez ceci, simple et facile
System.getProperty("os.name");
System.getProperty("os.version");
System.getProperty("os.Arch");
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
\
Je trouve que le OS Utils de Swingx fait le travail.
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
String osName = System.getProperty("os.name");
System.out.println("Operating system " + osName);
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;
}
}
Vous pouvez simplement utiliser la méthode Sun.awt.OSInfo # getOSType ()
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));
}
}
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.VM
class
n'est pas destiné à être utilisé par public
. Par conséquent, vous ne devriez pas l'utiliser dans le code de production!
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.
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
}