public
Last active

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.

  • Download Gist
Find-JavaExe.ps1
PowerShell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
function Find-JavaExe {
<#
 
.SYNOPSIS
 
Locates java.exe on the current system via common conventions.
 
 
.DESCRIPTION
 
Searches $env:JAVAHOME, path variables, and the registry (http://stackoverflow.com/a/5415532/211747)
 
 
.EXAMPLE
 
Find java.exe, or throw an error if it can't be found.
 
$JavaExePath = Find-JavaExe
 
 
.EXAMPLE
 
Find java.exe, or return null if it can't be found.
 
$JavaExePathOrNull = Find-JavaExe -ErrorAction SilentlyContinue
 
#>
[CmdletBinding()]
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.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.