How to get operating system in Java - java

I know there is such a question on SO, but I could not find it. So asking again...
I need to set up properties to my program, but I need to make it OS indipendent - running both on Windows XP and Linux (unknown distro, unknown version)
More specifically - I need to set up to the system where to find the chromedriver binary. I need something like this pseudocode:
if (getOs() == Windows){
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, "chromedriver.exe");
} else{
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, "chromedriver");
}
Now I need the part for getting the OS. Thanks for help.

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

You can use the utility class I wrote, you just need to copy the following class in your project
https://github.com/aurbroszniowski/os-platform-finder/blob/master/src/main/java/org/jsoftbiz/utils/OS.java
Then do:
import org.jsoftbiz.utils.OS;
OS myOS = OS.getOs();
myOS.getPlatformName()
myOS.getName()
myOS.getVersion()
myOS.getArch()

oslib is a library that provides information about the current OS. You won't need to parse the info you get from System.getProperty("os.name");.
Note: Most operating systems are tested and supported but some are not yet implemented. For a complete list check out their Github.
Code for your specific problem:
AbstractOperatingSystem os = OperatingSystem.getOperatingSystem();
if (os.getType == OperatingSystem.WINDOWS){
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, "chromedriver.exe");
} else if(os.getType == OperatingSystem.LINUX) {
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, "chromedriver");
} else {
throw new Exception("Unsupported OS.");
}

Related

Java check if program is installed on windows

Is there a way to check if a specific program is installed on Windows using Java?
I'm trying to develop a Java program that automatically creates zip archives by using the code line command from 7-Zip.
So, I would like to check in Java if on my windows OS '7-Zip' is already installed. No check for running apps or if OS is Windows or Linux. I want to get a bool (true/false) if '7-Zip' is installed on Windows.
The library Apache Commons has a class called SystemUtils - full documentation is available at https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SystemUtils.html.
In this library you have the following static boolean properties at your disposal:
SystemUtils.IS_OS_LINUX
SystemUtils.IS_OS_WINDOWS
The unix-like solution would be to simply try to run the program with --version flag (on windows probably the /? or - like in the 7zip case - without any at all) and check whether it fails, or what the return code will be.
Something like:
public boolean is7zipInstalled() {
try {
Process process = Runtime.getRuntime().exec("7zip.exe");
int code = process.waitFor();
return code == 0;
} catch (Exception e) {
return false;
}
}
I assume that you're talking about Windows. As Java is intended to be a platform-independent language and the way how to determine it differs per platform, there's no standard Java API to check that. You can however do it with help of JNI calls on a DLL which crawls the Windows registry. You can then just check if the registry key associated with the software is present in the registry. There's a 3rd party Java API with which you can crawl the Windows registry: jRegistryKey.
Here's an SSCCE with help of jRegistryKey:
package com.stackoverflow.q2439984;
import java.io.File;
import java.util.Iterator;
import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RootKey;
public class Test {
public static void main(String... args) throws Exception {
RegistryKey.initialize(Test.class.getResource("jRegistryKey.dll").getFile());
RegistryKey key = new RegistryKey(RootKey.HKLM, "Software\\Mozilla");
for (Iterator<RegistryKey> subkeys = key.subkeys(); subkeys.hasNext();) {
RegistryKey subkey = subkeys.next();
System.out.println(subkey.getName()); // You need to check here if there's anything which matches "Mozilla FireFox".
}
}
}
If you however intend to have a platformindependent application, then you'll also have to take into account the Linux/UNIX/Mac/Solaris/etc. (in other words: anywhere where Java is able to run) ways to detect whether FF is installed. Else you'll have to distribute it as a Windows-only application and do a System#exit() along with a warning whenever System.getProperty("os.name") is not Windows.
Sorry, I don't know how to detect in other platforms whether FF is installed or not, so don't expect an answer from me for that ;)

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

In Java, we can see the property value of os.name to know the name of the underlying operating system: System.getProperty("os.name").
For each edition of Windows, it used to return always the exact name of the OS: Windows XP for XP, Windows Vista for Vista, Windows 7 for Seven, Windows 8.1 for 8.1, and so on...
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:
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 -?
This is a known problem JDK-8066504 that has been fixed in upcoming Java 8 update 60.
The reason is GetVersionEx function has changed its behavior since Windows 8.1.
There are multiple possible workarounds, see MSDN article.
The trivial one is to exec cmd.exe /c ver.
The other is to look at the version information of one of the system files, e.g. kernel32.dll.
This is definitely a known bug. It occurs because the os.name property gets its value from the GetVersionEx in the source code of the Windows API. GetVersionEx however,
may be altered or unavailable for releases after Windows 8.1
As per Microsoft's official website. Instead, we will need to use the IsWindows10OrGreater found in the Version Helper API functions in the versionhelpers.h file. 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 tutorial will help you do it. Another solution is shown in this bug log, and does require less effort.
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:
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;
}
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-b11 for me), but it is correct now: os.name gives me Windows 10.
Besides, if you don't trust it, you can check os.version. I have 10.0.
(By the way, I see os.arch:amd64. This is of JVM, not of OS. )
You could also use the .contains() method and just check for the "windows"
string maybe along the lines of
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.
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:
the if statement is just a conditional to determine the version of windows
The System.getProperty("os.name") returns the name of the os as a string
The .toLowerCase() method makes that returned String lower case
The .contains(String) method checks if the given input string is contained in the String it is being called on
The last statement allows for different code for each os except 8.1 & 10 which would need to be handled as one block :(

Accessing 64-bit Registry in 32-bit application

Please do not mark this question as duplicate!
I'm searching for a solution in java - not C# - and used the WinRegistry class.
I wrote a program that can readout a registry key. Now the problem: the java application is 32bit and I want to read the reg-keys from a windows 7 64bit-system. With this code windows will redirect my 32bit program to the 32bit section of the 64bit-registry (compare the real path with the comment in the code - Wow6432Node!).
// only access to "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run"
value = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", "Citrix Login Service");
I deleted the try-catch-block so you are able to focus the real problem more better ;).
I solved this now - thanks goes to Petrucio who posted this solution in 2012: read/write to Windows Registry using Java.
E.g. - Read Operation:
try {
String value = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", "TestValue", WinRegistry.KEY_WOW64_64KEY);
System.out.println(value);
} catch (Exception ex) {
ex.printStackTrace();
}
I hope that is usefully for someone.

Shutting down windows operating system using Java code

I'm trying the following Java code to shut down Windows operating system. I'm using Microsoft Windows XP Professional version 2002, Service pack 3 with Intel(R) Core(TM) i3 CPU using Netbeans IDE 6.9.1.
package shutdownos;
import java.io.IOException;
final public class Main
{
public static void main(String... args) throws IOException
{
String shutdownCommand="";
String operatingSystem = System.getProperty("os.name");
if ("Linux".equals(operatingSystem) || "Mac OS X".equals(operatingSystem))
{
shutdownCommand = "shutdown -h now";
}
else if ("Windows".equals(operatingSystem))
{
shutdownCommand = "shutdown.exe -s -t 0";
}
else
{
//throw new RuntimeException("Unsupported operating system.");
}
Runtime.getRuntime().exec(shutdownCommand);
System.exit(0);
}
}
It throws the following exception in Java.
Exception in thread "main" java.lang.IllegalArgumentException: Empty command
The exception occurs on the following line in the above code.
Runtime.getRuntime().exec(shutdownCommand);
The second-last in the main() method. What is wrong with this code?
You're looking for the wrong value of os.name -- whatever it is, it's not "Windows" and therefore the code runs through the else block where the variable shudowncommand is left as an empty string, which causes the "Empty command" exception. Do a System.out.println(operatingSystem) to see what value you should check for instead of "Windows".
It's probably something like "Windows NT", so if you replace the .equals() check by a .startsWith() check you should be set.
According to this page, you seem to be using the wrong value for O/S names. If that is the case, your shutdownCommand string will remain empty, which will cause your program to pass an empty command, which conforms with the exception you are getting.
the program is skipping both the if statements, os.name would not be just Windows, it would be i think Windows XP or more, so replace that with starts with
else if (operatingSystem.startsWith("Windows")){
}
There is no property "os.name" that is equal to "Windows". Did you mean to check for if the property contains "Windows"?. As far as I know all window os names have a quantifier such as "Windows 95", "Windows NT" etc.
The shutdown command for windows os should be shutdown -s -t 0. try with this.
I mostly use this site to find out the possible values: What os or arch value can I use?
As others said, you should use String.startsWith() method.

How to open user system preferred editor for given file?

I'm trying to figure out how to open the system preferred editor for a given file.
Say, we have a file manager, written in Java. User goes to folder and sees the list of files. And, for example, there is a file Icon.jpg. User double clicks on the filename and file opens in system's preferred editor (i.e. Gimp). The main issue is - how to do that?
We can do Runtime.getRuntime().exec("something file"), but this way you should know which program is preferred in user environment. But how?
We also are able to do Desktop.getDesktop().edit(File file), but this way we cannot track process and aren't able to know then this child process is closed. Other issue - function doesn't work on linux (at least on Ubuntu 8.10). There is also Desktop.getDesktop().open(File file), but it forces to open file viewer, instead of system viewer for that file type.
I am searching for a solution all week, but didn't got any suitable and generic one. Do you know the other approaches to this question? For my project it would be enough if it would work on Windows+Linux+Mac.
Thank you for your answers and advices.
Edit on 2009-02-08 23:04
Other suggestion: can I force "application selection" window in Windows and in Linux, as in Mac with "open file"? For example, then you trying to open file, you are being asked to choose application from list of system preferred ones? (something like "Open with..." in Windows explorer). Do you know?
Seems that if you can't use java.awt.Desktop you have to distinguish between the OSes:
Windows:
RUNDLL32.EXE SHELL32.DLL,OpenAs_RunDLL <file.ext>
Linux:
edit <file.ext>
Mac:
open <file.ext>
HTH. Obviously, that is not very portable...
Check out the java.awt.Desktop object. In your case, you want to invoke edit()
If you want to ensure that a given platform supports this call, then you can do something like the following (I have not tested this code):
public boolean editFile(final File file) {
if (!Desktop.isDesktopSupported()) {
return false;
}
Desktop desktop = Desktop.getDesktop();
if (!desktop.isSupported(Desktop.Action.EDIT)) {
return false;
}
try {
desktop.edit(file);
} catch (IOException e) {
// Log an error
return false;
}
return true;
}
This isn't cross-platform, but on Mac OS X you can do
Runtime.getRuntime().exec("open filename");
The open(1) executable uses LaunchServices to pick the right program to execute, and then uses that to open the file named filename.
This will work in windows
Runtime.getRuntime().exec( "CMD /C START filename.ext " );
For JavaFX applications, we can use HostServices. This question covers how to use HostServices. This should work on Ubuntu (tested)/Windows (not tested) and Mac (not tested).
import java.io.File;
import java.io.IOException;
public class App extends Application {
}
File file = new File("/your/file/path");
HostServices hostServices = getHostServices();
hostServices.showDocument(file.getAbsolutePath());
getHostServices() is a method of JavaFX Application class.

Categories

Resources