diff --git a/bin/WinLauncher/WinLauncher.exe b/bin/WinLauncher/WinLauncher.exe index 6cb990da3631..3f1317cddac5 100644 Binary files a/bin/WinLauncher/WinLauncher.exe and b/bin/WinLauncher/WinLauncher.exe differ diff --git a/bin/WinLauncher/WinLauncher64.exe b/bin/WinLauncher/WinLauncher64.exe index 4873c35f8832..6bcb49a9be53 100644 Binary files a/bin/WinLauncher/WinLauncher64.exe and b/bin/WinLauncher/WinLauncher64.exe differ diff --git a/bin/scripts/win/idea.bat b/bin/scripts/win/idea.bat index 5fb7dc3fcf6e..272051336291 100644 --- a/bin/scripts/win/idea.bat +++ b/bin/scripts/win/idea.bat @@ -10,6 +10,9 @@ :: --------------------------------------------------------------------- IF EXIST "%@@product_uc@@_JDK%" SET JDK=%@@product_uc@@_JDK% IF NOT "%JDK%" == "" GOTO jdk +SET USER_JDK_FILE=%USERPROFILE%\.@@system_selector@@\config\@@vm_options@@.jdk +IF EXIST "%USER_JDK_FILE%" set/pJDK=<%USER_JDK_FILE% +IF NOT "%JDK%" == "" GOTO jdk IF EXIST "%~dp0\..\jre" SET JDK=%~dp0\..\jre IF NOT "%JDK%" == "" GOTO jdk IF EXIST "%JDK_HOME%" SET JDK=%JDK_HOME% diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp index 93c03bd7a2dc..af7a8fb266d4 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.cpp +++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp @@ -44,6 +44,8 @@ bool need64BitJRE = false; #define BITS_STR "32-bit" #endif +void TrimLine(char* line); + std::string EncodeWideACP(const std::wstring &str) { int cbANSI = WideCharToMultiByte(CP_ACP, 0, str.c_str(), str.size(), NULL, 0, NULL, NULL); @@ -143,6 +145,34 @@ bool FindJVMInEnvVar(const char* envVarName, bool& result) return false; } +bool FindJVMInSettings() { + TCHAR buffer[_MAX_PATH]; + TCHAR copy[_MAX_PATH]; + + GetModuleFileName(NULL, buffer, _MAX_PATH); + std::wstring module(buffer); + + if (LoadString(hInst, IDS_VM_OPTIONS_PATH, buffer, _MAX_PATH)) { + ExpandEnvironmentStrings(buffer, copy, _MAX_PATH - 1); + std::wstring path(copy); + path += L"\\config" + module.substr(module.find_last_of('\\')) + L".jdk"; + FILE *f = _tfopen(path.c_str(), _T("rt")); + if (!f) return false; + + char line[_MAX_PATH]; + if (!fgets(line, _MAX_PATH, f)) { + fclose(f); + return false; + } + + TrimLine(line); + fclose(f); + + return FindValidJVM(line); + } + return false; +} + bool FindJVMInRegistryKey(const char* key, bool wow64_32) { HKEY hKey; @@ -224,6 +254,8 @@ bool LocateJVM() return result; } + if (FindJVMInSettings()) return true; + std::vector jrePaths; if(need64BitJRE) jrePaths.push_back(GetAdjacentDir("jre64")); jrePaths.push_back(GetAdjacentDir("jre")); diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java index 6a9274a5a610..8571ac0e120f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java @@ -50,7 +50,8 @@ import java.util.Locale; */ public class SwitchBootJdkAction extends AnAction implements DumbAware { @NonNls private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.SwitchBootJdkAction"); - @NonNls private static final String productJdkConfigFileName = getExecutable() + ".jdk"; + @NonNls private static final String productJdkConfigFileName = + getExecutable() + (SystemInfo.isWindows ? ((SystemInfo.is64Bit) ? "64.exe.jdk" : ".exe.jdk") : ".jdk"); @NonNls private static final File productJdkConfigFile = new File(PathManager.getConfigPath(), productJdkConfigFileName); @NonNls private static final File bundledJdkFile = getBundledJDKFile(); @@ -67,11 +68,6 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { @Override public void update(AnActionEvent e) { - Presentation presentation = e.getPresentation(); - if (!(SystemInfo.isMac || SystemInfo.isLinux)) { - presentation.setEnabledAndVisible(false); - return; - } e.getPresentation().setText("Switch Boot JDK"); } @@ -233,6 +229,9 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { "/usr/lib/jvm/", // Ubuntu "/usr/java/" // Fedora }; + private static final String STANDARD_JVM_X64_LOCATIONS_ON_WINDOWS = "Program Files/Java"; + + private static final String STANDARD_JVM_X86_LOCATIONS_ON_WINDOWS = "Program Files (x86)/Java"; private static final Version JDK8_VERSION = new Version(1, 8, 0); @@ -260,6 +259,16 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { jdkBundleList.addBundlesFromLocation(location, JDK8_VERSION, null); } } + else if (SystemInfo.isWindows) { + for (File root : File.listRoots()) { + if (SystemInfo.is32Bit) { + jdkBundleList.addBundlesFromLocation(new File(root, STANDARD_JVM_X86_LOCATIONS_ON_WINDOWS).getAbsolutePath(), JDK8_VERSION, null); + } + else { + jdkBundleList.addBundlesFromLocation(new File(root, STANDARD_JVM_X64_LOCATIONS_ON_WINDOWS).getAbsolutePath(), JDK8_VERSION, null); + } + } + } return jdkBundleList; } diff --git a/platform/lang-impl/src/com/intellij/util/JdkBundle.java b/platform/lang-impl/src/com/intellij/util/JdkBundle.java index f39918fbdccc..2ac187193acc 100644 --- a/platform/lang-impl/src/com/intellij/util/JdkBundle.java +++ b/platform/lang-impl/src/com/intellij/util/JdkBundle.java @@ -27,17 +27,22 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.List; import java.util.regex.Pattern; public class JdkBundle { @NotNull private static final Logger LOG = Logger.getInstance("#com.intellij.util.JdkBundle"); + @NotNull private static final Pattern[] VERSION_UPDATE_PATTERNS = { Pattern.compile("^java version \"([\\d]+\\.[\\d]+\\.[\\d]+)_([\\d]+)\".*", Pattern.MULTILINE), Pattern.compile("^openjdk version \"([\\d]+\\.[\\d]+\\.[\\d]+)_([\\d]+).*\".*", Pattern.MULTILINE), Pattern.compile("^[a-zA-Z() \"\\d]*([\\d]+\\.[\\d]+\\.?[\\d]*).*", Pattern.MULTILINE) }; + @NotNull + private static final Pattern ARCH_64_BIT_PATTERN = Pattern.compile(".*64-Bit.*", Pattern.MULTILINE); + @NotNull private File myBundleAsFile; @NotNull private String myBundleName; @Nullable private Pair myVersionUpdate; @@ -76,14 +81,17 @@ public class JdkBundle { if (!SystemInfo.isMac && !isValidBundle) return null; // Skip jre File absJvmLocation = bundled ? new File(PathManager.getHomePath(), jvm.getPath()) : jvm; - Pair> nameVersionAndUpdate = getJDKNameVersionAndUpdate(absJvmLocation, homeSubPath); + Pair, Pair> nameArchVersionAndUpdate = getJDKNameArchVersionAndUpdate(absJvmLocation, homeSubPath); + if (nameArchVersionAndUpdate.first.second == null || (nameArchVersionAndUpdate.first.second != SystemInfo.is64Bit)) { + return null; // Skip unknown or incompatible arch + } - if (SystemInfo.isMac && nameVersionAndUpdate.second != null && nameVersionAndUpdate.second.first.isOrGreaterThan(1, 7) && + if (SystemInfo.isMac && nameArchVersionAndUpdate.second != null && nameArchVersionAndUpdate.second.first.isOrGreaterThan(1, 7) && !isValidBundle) { return null; // Skip jre } - return new JdkBundle(jvm, nameVersionAndUpdate.first, nameVersionAndUpdate.second, boot, bundled); + return new JdkBundle(jvm, nameArchVersionAndUpdate.first.first, nameArchVersionAndUpdate.second, boot, bundled); } @Nullable @@ -154,23 +162,26 @@ public class JdkBundle { return myBundleName + ((myVersionUpdate != null) ? myVersionUpdate.first.toString() : ""); } - private static Pair> getJDKNameVersionAndUpdate(File jvm, String homeSubPath) { + private static Pair, Pair> getJDKNameArchVersionAndUpdate(File jvm, String homeSubPath) { GeneralCommandLine commandLine = new GeneralCommandLine().withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.NONE); commandLine.setExePath(new File(jvm, homeSubPath + File.separator + "jre" + File.separator + "bin" + File.separator + "java").getAbsolutePath()); commandLine.addParameter("-version"); - String displayVersion = null; + String displayVersion; + Boolean is64Bit = null; Pair versionAndUpdate = null; + List outputLines = null; + try { - displayVersion = ExecUtil.readFirstLine(commandLine.createProcess().getErrorStream(), null); + outputLines = ExecUtil.execAndGetOutput(commandLine).getStderrLines(); } catch (ExecutionException e) { // Checking for jdk 6 on mac if (SystemInfo.isMac) { commandLine.setExePath(new File(jvm, homeSubPath + File.separator + "bin" + File.separator + "java").getAbsolutePath()); try { - displayVersion = ExecUtil.readFirstLine(commandLine.createProcess().getErrorStream(), null); + outputLines = ExecUtil.execAndGetOutput(commandLine).getStderrLines(); } catch (ExecutionException e1) { LOG.debug(e); @@ -179,15 +190,20 @@ public class JdkBundle { LOG.debug(e); } - if (displayVersion != null) { - versionAndUpdate = VersionUtil.parseVersionAndUpdate(displayVersion, VERSION_UPDATE_PATTERNS); - displayVersion = displayVersion.replaceFirst("\".*\"", ""); + if (outputLines != null && outputLines.size() >= 1) { + String versionLine = outputLines.get(0); + versionAndUpdate = VersionUtil.parseVersionAndUpdate(versionLine, VERSION_UPDATE_PATTERNS); + displayVersion = versionLine.replaceFirst("\".*\"", ""); + if (outputLines.size() >= 3) { + String archLine = outputLines.get(2); + is64Bit = ARCH_64_BIT_PATTERN.matcher(archLine).find(); + } } else { displayVersion = jvm.getName(); } - return Pair.create(displayVersion, versionAndUpdate); + return Pair.create(Pair.create(displayVersion, is64Bit), versionAndUpdate); } public boolean isBundled() { diff --git a/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java b/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java index 84f470b7ea9e..cee75f9b92ef 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java @@ -117,7 +117,6 @@ public class JdkBundleTest { @Test public void testCreateBundle() throws Exception { - if (SystemInfo.isWindows) return; // Windows is not supported so far File homeJDK = new File(System.getProperty("java.home")).getParentFile(); if (!new File(homeJDK, "lib/tools.jar").exists()) return; // Skip pure jre @@ -145,7 +144,6 @@ public class JdkBundleTest { @Test public void testCreateBoot() throws Exception { - if (SystemInfo.isWindows) return; // Windows is not supported so far File homeJDK = new File(System.getProperty("java.home")).getParentFile(); if (!new File(homeJDK, "lib/tools.jar").exists()) return; // Skip pure jre