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