1d2d6999d779fffe976c55db04bf523907a8743edRaphael/* 2d2d6999d779fffe976c55db04bf523907a8743edRaphael * Copyright (C) 2012 The Android Open Source Project 3d2d6999d779fffe976c55db04bf523907a8743edRaphael * 4d2d6999d779fffe976c55db04bf523907a8743edRaphael * Licensed under the Apache License, Version 2.0 (the "License"); 5d2d6999d779fffe976c55db04bf523907a8743edRaphael * you may not use this file except in compliance with the License. 6d2d6999d779fffe976c55db04bf523907a8743edRaphael * You may obtain a copy of the License at 7d2d6999d779fffe976c55db04bf523907a8743edRaphael * 8d2d6999d779fffe976c55db04bf523907a8743edRaphael * http://www.apache.org/licenses/LICENSE-2.0 9d2d6999d779fffe976c55db04bf523907a8743edRaphael * 10d2d6999d779fffe976c55db04bf523907a8743edRaphael * Unless required by applicable law or agreed to in writing, software 11d2d6999d779fffe976c55db04bf523907a8743edRaphael * distributed under the License is distributed on an "AS IS" BASIS, 12d2d6999d779fffe976c55db04bf523907a8743edRaphael * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2d6999d779fffe976c55db04bf523907a8743edRaphael * See the License for the specific language governing permissions and 14d2d6999d779fffe976c55db04bf523907a8743edRaphael * limitations under the License. 15d2d6999d779fffe976c55db04bf523907a8743edRaphael */ 16d2d6999d779fffe976c55db04bf523907a8743edRaphael 17d2d6999d779fffe976c55db04bf523907a8743edRaphael/* 18d2d6999d779fffe976c55db04bf523907a8743edRaphael * "find_java.exe", for Windows only. 19d2d6999d779fffe976c55db04bf523907a8743edRaphael * Tries to find a Java binary in a variety of places and prints the 20d2d6999d779fffe976c55db04bf523907a8743edRaphael * first one found on STDOUT and returns 0. 21d2d6999d779fffe976c55db04bf523907a8743edRaphael * 22d2d6999d779fffe976c55db04bf523907a8743edRaphael * If not found, returns error 1 with no message 23d2d6999d779fffe976c55db04bf523907a8743edRaphael * (unless ANDROID_SDKMAN_DEBUG or -d if set, in which case there's a message on STDERR). 24d2d6999d779fffe976c55db04bf523907a8743edRaphael * 25d2d6999d779fffe976c55db04bf523907a8743edRaphael * Implementation details: 26d2d6999d779fffe976c55db04bf523907a8743edRaphael * - We don't have access to ATL or MFC. 27d2d6999d779fffe976c55db04bf523907a8743edRaphael * - We don't want to pull in things like STL. 28d2d6999d779fffe976c55db04bf523907a8743edRaphael * - No Unicode/MBCS support for now. 29d2d6999d779fffe976c55db04bf523907a8743edRaphael * 30d2d6999d779fffe976c55db04bf523907a8743edRaphael * TODO for later version: 31d2d6999d779fffe976c55db04bf523907a8743edRaphael * - provide an env variable to let users override which version is being used. 32d2d6999d779fffe976c55db04bf523907a8743edRaphael * - if there's more than one java.exe found, enumerate them all. 33d2d6999d779fffe976c55db04bf523907a8743edRaphael * - and in that case take the one with the highest Java version number. 34d2d6999d779fffe976c55db04bf523907a8743edRaphael * - since that operation is expensive, do it only once and cache the result 35d2d6999d779fffe976c55db04bf523907a8743edRaphael * in a temp file. If the temp file is not found or the java binary no 36d2d6999d779fffe976c55db04bf523907a8743edRaphael * longer exists, re-run the enumaration. 37d2d6999d779fffe976c55db04bf523907a8743edRaphael */ 38d2d6999d779fffe976c55db04bf523907a8743edRaphael 39d2d6999d779fffe976c55db04bf523907a8743edRaphael#ifdef _WIN32 40d2d6999d779fffe976c55db04bf523907a8743edRaphael 41d2d6999d779fffe976c55db04bf523907a8743edRaphael#include "utils.h" 42d2d6999d779fffe976c55db04bf523907a8743edRaphael#include "find_java.h" 43d2d6999d779fffe976c55db04bf523907a8743edRaphael#include <io.h> 44d2d6999d779fffe976c55db04bf523907a8743edRaphael#include <fcntl.h> 45d2d6999d779fffe976c55db04bf523907a8743edRaphael 46d2d6999d779fffe976c55db04bf523907a8743edRaphaelstatic void testFindJava() { 47d2d6999d779fffe976c55db04bf523907a8743edRaphael 48d2d6999d779fffe976c55db04bf523907a8743edRaphael CPath javaPath("<not found>"); 496123b532fc0e57e33a09dc429f8ec708a88aedccRaphael int v = findJavaInEnvPath(&javaPath); 506123b532fc0e57e33a09dc429f8ec708a88aedccRaphael printf("findJavaInEnvPath: [%d] %s\n", v, javaPath.cstr()); 51d2d6999d779fffe976c55db04bf523907a8743edRaphael 52d2d6999d779fffe976c55db04bf523907a8743edRaphael javaPath.set("<not found>"); 536123b532fc0e57e33a09dc429f8ec708a88aedccRaphael v = findJavaInRegistry(&javaPath); 546123b532fc0e57e33a09dc429f8ec708a88aedccRaphael printf("findJavaInRegistry [%d] %s\n", v, javaPath.cstr()); 55d2d6999d779fffe976c55db04bf523907a8743edRaphael 56d2d6999d779fffe976c55db04bf523907a8743edRaphael javaPath.set("<not found>"); 576123b532fc0e57e33a09dc429f8ec708a88aedccRaphael v = findJavaInProgramFiles(&javaPath); 586123b532fc0e57e33a09dc429f8ec708a88aedccRaphael printf("findJavaInProgramFiles [%d] %s\n", v, javaPath.cstr()); 59d2d6999d779fffe976c55db04bf523907a8743edRaphael} 60d2d6999d779fffe976c55db04bf523907a8743edRaphael 61d2d6999d779fffe976c55db04bf523907a8743edRaphael 62d2d6999d779fffe976c55db04bf523907a8743edRaphaelint main(int argc, char* argv[]) { 63d2d6999d779fffe976c55db04bf523907a8743edRaphael 64d2d6999d779fffe976c55db04bf523907a8743edRaphael gIsConsole = true; // tell utils to to print errors to stderr 65d2d6999d779fffe976c55db04bf523907a8743edRaphael gIsDebug = (getenv("ANDROID_SDKMAN_DEBUG") != NULL); 66d2d6999d779fffe976c55db04bf523907a8743edRaphael bool doShortPath = false; 67d2d6999d779fffe976c55db04bf523907a8743edRaphael bool doVersion = false; 68a418de56908e413187e1144b7d1d430bbfc459d5Raphael bool doJavaW = false; 69d2d6999d779fffe976c55db04bf523907a8743edRaphael 70d2d6999d779fffe976c55db04bf523907a8743edRaphael for (int i = 1; i < argc; i++) { 71d2d6999d779fffe976c55db04bf523907a8743edRaphael if (strncmp(argv[i], "-t", 2) == 0) { 72d2d6999d779fffe976c55db04bf523907a8743edRaphael testFindJava(); 73d2d6999d779fffe976c55db04bf523907a8743edRaphael return 0; 74d2d6999d779fffe976c55db04bf523907a8743edRaphael 75d2d6999d779fffe976c55db04bf523907a8743edRaphael } else if (strncmp(argv[i], "-d", 2) == 0) { 76d2d6999d779fffe976c55db04bf523907a8743edRaphael gIsDebug = true; 77d2d6999d779fffe976c55db04bf523907a8743edRaphael 78d2d6999d779fffe976c55db04bf523907a8743edRaphael } else if (strncmp(argv[i], "-s", 2) == 0) { 79d2d6999d779fffe976c55db04bf523907a8743edRaphael doShortPath = true; 80d2d6999d779fffe976c55db04bf523907a8743edRaphael 81d2d6999d779fffe976c55db04bf523907a8743edRaphael } else if (strncmp(argv[i], "-v", 2) == 0) { 82d2d6999d779fffe976c55db04bf523907a8743edRaphael doVersion = true; 83d2d6999d779fffe976c55db04bf523907a8743edRaphael 84a418de56908e413187e1144b7d1d430bbfc459d5Raphael } else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "-javaw") == 0) { 85a418de56908e413187e1144b7d1d430bbfc459d5Raphael doJavaW = true; 86a418de56908e413187e1144b7d1d430bbfc459d5Raphael 87d2d6999d779fffe976c55db04bf523907a8743edRaphael } else { 88d2d6999d779fffe976c55db04bf523907a8743edRaphael printf( 89d2d6999d779fffe976c55db04bf523907a8743edRaphael "Outputs the path of the first Java.exe found on the local system.\n" 90d2d6999d779fffe976c55db04bf523907a8743edRaphael "Returns code 0 when found, 1 when not found.\n" 91d2d6999d779fffe976c55db04bf523907a8743edRaphael "Options:\n" 92d2d6999d779fffe976c55db04bf523907a8743edRaphael "-h / -help : This help.\n" 93d2d6999d779fffe976c55db04bf523907a8743edRaphael "-t / -test : Internal test.\n" 94d2d6999d779fffe976c55db04bf523907a8743edRaphael "-s / -short : Print path in short DOS form.\n" 95a418de56908e413187e1144b7d1d430bbfc459d5Raphael "-w / -javaw : Search a matching javaw.exe; defaults to java.exe if not found.\n" 96d2d6999d779fffe976c55db04bf523907a8743edRaphael "-v / -version: Only prints the Java version found.\n" 97d2d6999d779fffe976c55db04bf523907a8743edRaphael ); 98d2d6999d779fffe976c55db04bf523907a8743edRaphael return 2; 99d2d6999d779fffe976c55db04bf523907a8743edRaphael } 100d2d6999d779fffe976c55db04bf523907a8743edRaphael } 101d2d6999d779fffe976c55db04bf523907a8743edRaphael 1026123b532fc0e57e33a09dc429f8ec708a88aedccRaphael // Find the first suitable version of Java we can use. 103d2d6999d779fffe976c55db04bf523907a8743edRaphael CPath javaPath; 1046123b532fc0e57e33a09dc429f8ec708a88aedccRaphael int version = findJavaInEnvPath(&javaPath); 1056123b532fc0e57e33a09dc429f8ec708a88aedccRaphael if (version < MIN_JAVA_VERSION) { 1066123b532fc0e57e33a09dc429f8ec708a88aedccRaphael version = findJavaInRegistry(&javaPath); 1076123b532fc0e57e33a09dc429f8ec708a88aedccRaphael } 1086123b532fc0e57e33a09dc429f8ec708a88aedccRaphael if (version < MIN_JAVA_VERSION) { 1096123b532fc0e57e33a09dc429f8ec708a88aedccRaphael version = findJavaInProgramFiles(&javaPath); 1106123b532fc0e57e33a09dc429f8ec708a88aedccRaphael } 1116123b532fc0e57e33a09dc429f8ec708a88aedccRaphael if (version < MIN_JAVA_VERSION || javaPath.isEmpty()) { 1126123b532fc0e57e33a09dc429f8ec708a88aedccRaphael if (gIsDebug) { 1136123b532fc0e57e33a09dc429f8ec708a88aedccRaphael fprintf(stderr, "Failed to find Java on your system.\n"); 1146123b532fc0e57e33a09dc429f8ec708a88aedccRaphael } 1156123b532fc0e57e33a09dc429f8ec708a88aedccRaphael return 1; 116d2d6999d779fffe976c55db04bf523907a8743edRaphael } 117d2d6999d779fffe976c55db04bf523907a8743edRaphael _ASSERT(!javaPath.isEmpty()); 118d2d6999d779fffe976c55db04bf523907a8743edRaphael 119d2d6999d779fffe976c55db04bf523907a8743edRaphael if (doShortPath) { 12026a423a5de4b715a980a0c0f0a16ec50bf39aef2Raphael Moll PVOID oldWow64Value = disableWow64FsRedirection(); 121d2d6999d779fffe976c55db04bf523907a8743edRaphael if (!javaPath.toShortPath(&javaPath)) { 12226a423a5de4b715a980a0c0f0a16ec50bf39aef2Raphael Moll revertWow64FsRedirection(&oldWow64Value); 123d2d6999d779fffe976c55db04bf523907a8743edRaphael fprintf(stderr, 124d2d6999d779fffe976c55db04bf523907a8743edRaphael "Failed to convert path to a short DOS path: %s\n", 125d2d6999d779fffe976c55db04bf523907a8743edRaphael javaPath.cstr()); 126d2d6999d779fffe976c55db04bf523907a8743edRaphael return 1; 127d2d6999d779fffe976c55db04bf523907a8743edRaphael } 12826a423a5de4b715a980a0c0f0a16ec50bf39aef2Raphael Moll revertWow64FsRedirection(&oldWow64Value); 129d2d6999d779fffe976c55db04bf523907a8743edRaphael } 130d2d6999d779fffe976c55db04bf523907a8743edRaphael 131d2d6999d779fffe976c55db04bf523907a8743edRaphael if (doVersion) { 1326123b532fc0e57e33a09dc429f8ec708a88aedccRaphael // Print version found. We already have the version as an integer 1336123b532fc0e57e33a09dc429f8ec708a88aedccRaphael // so we don't need to run java -version a second time. 1346123b532fc0e57e33a09dc429f8ec708a88aedccRaphael printf("%d.%d", version / 1000, version % 1000); 1356123b532fc0e57e33a09dc429f8ec708a88aedccRaphael return 0; 136d2d6999d779fffe976c55db04bf523907a8743edRaphael } 137d2d6999d779fffe976c55db04bf523907a8743edRaphael 138a418de56908e413187e1144b7d1d430bbfc459d5Raphael if (doJavaW) { 139a418de56908e413187e1144b7d1d430bbfc459d5Raphael // Try to find a javaw.exe instead of java.exe at the same location. 140a418de56908e413187e1144b7d1d430bbfc459d5Raphael CPath javawPath(javaPath); 141a418de56908e413187e1144b7d1d430bbfc459d5Raphael javawPath.replaceName("java.exe", "javaw.exe"); 142a418de56908e413187e1144b7d1d430bbfc459d5Raphael // Only accept it if we can actually find the exec 143a418de56908e413187e1144b7d1d430bbfc459d5Raphael PVOID oldWow64Value = disableWow64FsRedirection(); 144a418de56908e413187e1144b7d1d430bbfc459d5Raphael if (javawPath.fileExists()) { 145a418de56908e413187e1144b7d1d430bbfc459d5Raphael javaPath.set(javawPath.cstr()); 146a418de56908e413187e1144b7d1d430bbfc459d5Raphael } 147a418de56908e413187e1144b7d1d430bbfc459d5Raphael revertWow64FsRedirection(&oldWow64Value); 148a418de56908e413187e1144b7d1d430bbfc459d5Raphael } 149a418de56908e413187e1144b7d1d430bbfc459d5Raphael 150d2d6999d779fffe976c55db04bf523907a8743edRaphael // Print java.exe path found 151d2d6999d779fffe976c55db04bf523907a8743edRaphael printf("%s", javaPath.cstr()); 152d2d6999d779fffe976c55db04bf523907a8743edRaphael return 0; 153d2d6999d779fffe976c55db04bf523907a8743edRaphael} 154d2d6999d779fffe976c55db04bf523907a8743edRaphael 155d2d6999d779fffe976c55db04bf523907a8743edRaphael#endif /* _WIN32 */ 156