Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
Attempting to find java.exe, on a Windows machine, in a way that's semi-reliable across Java versions, operating system versions, 32 vs 64-bit and whatever else can be thrown at us.
function Find-JavaExe {
Locates java.exe on the current system via common conventions.
Searches $env:JAVAHOME, path variables, and the registry (
Find java.exe, or throw an error if it can't be found.
$JavaExePath = Find-JavaExe
Find java.exe, or return null if it can't be found.
$JavaExePathOrNull = Find-JavaExe -ErrorAction SilentlyContinue
param ()
$JavaExeSuffix = 'bin\java.exe'
if ($env:JAVAHOME -eq $null) {
Write-Debug "`$env:JAVAHOME doesn't exist, going to look elsewhere"
else {
$JavaHomeBasedPath = Join-Path $env:JAVAHOME $JavaExeSuffix
Write-Debug "Testing for $JavaHomeBasedPath, based on `$env:JAVAHOME"
if (Test-Path $JavaHomeBasedPath) {
Write-Debug "Found $JavaExePath"
return $JavaExePath
$FileSearchPaths = $env:Path.Split(';')
$JavaExePath = $FileSearchPaths |
where {
$PotentialPath = Join-Path $_ $JavaExeSuffix
Write-Debug "Testing for $PotentialPath, based on path variable $_"
if (Test-Path $PotentialPath) { $PotentialPath }
} |
select -First 1
if ($JavaExePath -ne $null) {
Write-Debug "Found $JavaExePath"
return $JavaExePath
$RegistrySearchPaths = @('HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\', 'HKLM:\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment\')
$JavaExePath = $RegistrySearchPaths |
where { Test-Path $_ } |
% {
$CurrentVersion = (Get-ItemProperty $_).CurrentVersion
Write-Debug "Current Java version is $CurrentVersion, based on $($_)"
$VersionKey = Join-Path $_ $CurrentVersion
$JavaHomeBasedPath = Join-Path (Get-ItemProperty $VersionKey).JavaHome $JavaExeSuffix
Write-Debug "Testing for $JavaHomeBasedPath, based on $VersionKey\JavaHome"
if (Test-Path $JavaHomeBasedPath) { $JavaHomeBasedPath }
} |
select -First 1
if ($JavaExePath -ne $null) {
Write-Debug "Found $JavaExePath"
return $JavaExePath
Write-Error "We couldn't resolve java.exe. We looked for `$env:JAVAHOME, then checked environment paths and the registry. The full set of search paths were written to the debug output stream."

I seem to recall, but don't have a machine I can test it on to hand, that some JDK/JRE releases put java.exe in %WINSYSDIR%. I don't recall if that directory is explicitly or implicitly in the Windows PATH env variable.

If it isn't, you should also check there directly and early, as it's the version that will be found by most programs.


%WINSYSDIR% only contains a pseudo java executable, which reads the registry to check what the default Java version is, then passes on the execution including arguments to the real Java binary.


Also, here's my implementation. It avoids the registry and any other config, which are sometimes unreliable and just scans the Program directory for any Java directory that still has a \bin directory (Java updates sometimes remove old versions by deleting the \bin dir)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.