How to determine Windows Java installation location
Solution 1
You can do it through the registry. You were looking in the wrong place though. I knocked together a quick example for you:
private string GetJavaInstallationPath()
{
string environmentPath = Environment.GetEnvironmentVariable("JAVA_HOME");
if (!string.IsNullOrEmpty(environmentPath))
{
return environmentPath;
}
string javaKey = "SOFTWARE\\JavaSoft\\Java Runtime Environment\\";
using (Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(javaKey))
{
string currentVersion = rk.GetValue("CurrentVersion").ToString();
using (Microsoft.Win32.RegistryKey key = rk.OpenSubKey(currentVersion))
{
return key.GetValue("JavaHome").ToString();
}
}
}
Then to use it, just do the following:
string installPath = GetJavaInstallationPath();
string filePath = System.IO.Path.Combine(installPath, "bin\\Java.exe");
if (System.IO.File.Exists(filePath))
{
// We have a winner
}
Solution 2
Just a quick bump because i found a better solution than the owner picked answer.
I found that it works with only 32bit Java and today time, thats pretty outdated. Therefor I made a adjustment for 64bit systems. Hope this helps anyone else looking for a way to pull the paths.
private string GetJavaInstallationPath()
{
string environmentPath = Environment.GetEnvironmentVariable("JAVA_HOME");
if (!string.IsNullOrEmpty(environmentPath))
{
return environmentPath;
}
string javaKey = "SOFTWARE\\JavaSoft\\Java Runtime Environment\\";
if (!Environment.Is64BitOperatingSystem)
{
using (Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(javaKey))
{
string currentVersion = rk.GetValue("CurrentVersion").ToString();
using (Microsoft.Win32.RegistryKey key = rk.OpenSubKey(currentVersion))
{
return key.GetValue("JavaHome").ToString();
}
}
}
else
{
using (var view64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry64))
{
using (var clsid64 = view64.OpenSubKey(javaKey))
{
string currentVersion = clsid64.GetValue("CurrentVersion").ToString();
using (RegistryKey key = clsid64.OpenSubKey(currentVersion))
{
return key.GetValue("JavaHome").ToString();
}
}
}
}
}
Solution 3
Building on top of @GenericTypeTea question - this is a way how to check both on x32/x64.
static string GetJavaInstallationPath()
{
string environmentPath = Environment.GetEnvironmentVariable("JAVA_HOME");
if (!string.IsNullOrEmpty(environmentPath))
{
return environmentPath;
}
const string JAVA_KEY = "SOFTWARE\\JavaSoft\\Java Runtime Environment\\";
var localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
using (var rk = localKey.OpenSubKey(JAVA_KEY))
{
if (rk != null)
{
string currentVersion = rk.GetValue("CurrentVersion").ToString();
using (var key = rk.OpenSubKey(currentVersion))
{
return key.GetValue("JavaHome").ToString();
}
}
}
localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
using (var rk = localKey.OpenSubKey(JAVA_KEY))
{
if (rk != null)
{
string currentVersion = rk.GetValue("CurrentVersion").ToString();
using (var key = rk.OpenSubKey(currentVersion))
{
return key.GetValue("JavaHome").ToString();
}
}
}
return null;
}
Solution 4
As far as I know the idea is that the latest version of Java installed on the system is the first one found in the PATH environment variable, so you shouldn't need to look for any registry keys, just run the thing.
Try:
ProcessStartInfo info = new ProcessStartInfo("java.exe", "-jar somerandom.jar");
If it doesn't work make sure java.exe is in your path and let me know.
Lance
I live a dual life as a automation/software/web/mobile/graphic designer/developer for Corporate America... and indie game vigilante. By day I monkey the codes for The Rawlings Group, but by night I wear all of the many hats of Nekoyoubi Games (just kidding; haven't had an evening in years). Follow me on Twitter (@Nekoyoubi) if you're into that sort of thing, and watch as I say absolutely nothing. ;Þ
Updated on September 10, 2020Comments
-
Lance over 3 years
I'm trying to dynamically run a .jar from a C# assembly (using
Process.Start(info)
). Now, from a console application I am able to just run:ProcessStartInfo info = new ProcessStartInfo("java", "-jar somerandom.jar");
In an assembly, however, I keep getting a
Win32Exception
of "The system cannot find the file specified" and have to change the line to the full path of Java like so:ProcessStartInfo info = new ProcessStartInfo("C:\\Program Files\\Java\\jre6\\bin\\java.exe", "-jar somerandom.jar");
This obviously won't do. I need a way to dynamically (but declaratively) determine the installed location of Java.
I started thinking of looking to the registry, but when I got there I noticed that there were specific keys for the versions and that they could not even be guaranteed to be numeric (e.g. "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.6" and "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.6.0_20").
What would be the most reliable "long-haul" solution to finding the most up-to-date java.exe path from a C# application?
Thanks much in advance.
- EDIT -
Thanks to a combination of GenericTypeTea's and Stephen Cleary's answers, I have solved the issue with the following:
private String GetJavaInstallationPath() { String javaKey = "SOFTWARE\\JavaSoft\\Java Runtime Environment"; using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(javaKey)) { String currentVersion = baseKey.GetValue("CurrentVersion").ToString(); using (var homeKey = baseKey.OpenSubKey(currentVersion)) return homeKey.GetValue("JavaHome").ToString(); } }
-
Lance almost 14 yearsUnfortunately, no. If I check the
info.EnvironmentVariables["path"]
, it does not contain Java. On the other hand, if I just open a command prompt, I can just> java -jar somerandom.jar
all day, so I know it's supposed to be there. -
Grzenio almost 14 yearsCould you check which java.exe process runs when you run it from command prompt?
-
Grzenio almost 14 years@LanceMay, and also have you actually tried the version with extension after the name of the process?
-
Lance almost 14 yearsYes, and they both work and don't work respectively in both situations. There seems to be no difference between the two.
-
Lance almost 14 yearsThis looks perfect! Thanks for pointing out that I missed the
CurrentVersion
. I keep getting NullRef's onrk
, though. ;( -
Jürgen Steinblock almost 14 yearsIt is a common convention that the user can overwrite the "autodetected" java path with an environment variable called "JAVA_HOME". A programmer should respect hat and give that variable precedence: string java_path = Environment.GetEnvironmentVariable("JAVA_HOME") ?? GetJavaInstallationPath();
-
djdd87 almost 14 years@Lance - I'm not a java expert, so this is only a best-guess. Have you had a look to see if the key is there? @SchlaWiener - Updated my answer to reflect your comment (I think).
-
Lance almost 14 years@GenericTypeTea: Yes, it is there. The keys listed in my question exist (got them through RegEdit). @SchlaWiener: Thanks a ton for that. That's something I won't have to get kicked for later. ;)
-
djdd87 almost 14 years@Lance - I don't know why it's returning null if the key's there then. It's going to be down to you to debug it I'm afraid. Please report back if you find out why.
-
Lance almost 14 yearsEven though I'm looking right at the key, I can get no further than "HKEY_LOCAL_MACHINE\SOFTWARE". At first I thought it was a path vs. key problem (since I could get into the software key just fine, but not the path copied straight from RegEdit), but even explicitly calling an
OpenSubKey()
for each step, I can't get any deeper than SOFTWARE. -
djdd87 almost 14 yearsThat's strange. It just comes back as null? If there was a problem I would of thought it'd be a security issue, but that would through a security exception.
-
Lance almost 14 yearsFound it! Not that it solves anything, but I found that the issue is because I'm x64 and
LocalMachine
is routing me to a subkey under SOFTWARE w/o me asking to (i.e. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node). -
djdd87 almost 14 yearsWhy'd you accept? Thought you just said it didn't solve anything? No point accepting if you've not had your question answered.
-
Lance almost 14 yearsBecause your code was sound, and I'm sure will work perfectly over this next hurdle (which I believe has broken scope), which I am currently writing up into another question as to not drowned this one with scope-creep. I will certainly post an edit once the other is resolved so others can benefit.
-
SimplyInk about 8 yearsmsdn.microsoft.com/en-us/library/dd411615(v=vs.110).aspx On the 64-bit versions of Windows, portions of the registry are stored separately for 32-bit and 64-bit applications. There is a 32-bit view for 32-bit applications and a 64-bit view for 64-bit applications. If view is Registry64 but the remote machine is running a 32-bit operating system, the returned key will use the Registry32 view.
-
SimplyInk about 8 yearsTherefore just the call to open the key from the Registry64 view is enough to cover both 32/64-bit OS cases.