IDEA-149864 Switch boot JDK on Windows shouldn't appear since unavailable appcode/146.495 clion/146.498 dbe/146.499 idea/146.494 phpstorm/146.493 pycharm/146.497 pycharm/146.503 rubymine/146.501 webstorm/146.504
authorAlexey Ushakov <Alexey.Ushakov@jetbrains.com>
Wed, 9 Mar 2016 13:13:02 +0000 (16:13 +0300)
committerAlexey Ushakov <Alexey.Ushakov@jetbrains.com>
Thu, 10 Mar 2016 23:43:13 +0000 (02:43 +0300)
Updated WinLanuncher[64], idea.bat and jdk switcher to support windows

bin/WinLauncher/WinLauncher.exe
bin/WinLauncher/WinLauncher64.exe
bin/scripts/win/idea.bat
native/WinLauncher/WinLauncher/WinLauncher.cpp
platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java
platform/lang-impl/src/com/intellij/util/JdkBundle.java
platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java

index 6cb990da36312b24295eb642b2b5342042fc164b..3f1317cddac59946f077f79d188a7bcc8fccf703 100644 (file)
Binary files a/bin/WinLauncher/WinLauncher.exe and b/bin/WinLauncher/WinLauncher.exe differ
index 4873c35f883235e0f3a630cc466945adf3179b9a..6bcb49a9be5382c2fcdc8ce17793479d7fe8811c 100644 (file)
Binary files a/bin/WinLauncher/WinLauncher64.exe and b/bin/WinLauncher/WinLauncher64.exe differ
index 5fb7dc3fcf6efec38162fb39e34e440f6ee96181..27205133629125e25de0fc7d5d05f75955d5d92d 100644 (file)
@@ -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%
index 93c03bd7a2dc187d3f7987512473c24aabcd23da..af7a8fb266d49b6c168c701d45392d6178376652 100644 (file)
@@ -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<std::string> jrePaths;
   if(need64BitJRE) jrePaths.push_back(GetAdjacentDir("jre64"));
   jrePaths.push_back(GetAdjacentDir("jre"));
index 6a9274a5a610a1ee5e816dd43dabc87b7588b8c8..8571ac0e120fc91661fccfbbdb8b3f1f0f28171a 100644 (file)
@@ -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;
   }
index f39918fbdcccc97f094addb6e25bbcc1f7474722..2ac187193acc6279145d4ceb779a9743fffd3208 100644 (file)
@@ -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<Version, Integer> 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<String, Pair<Version, Integer>> nameVersionAndUpdate = getJDKNameVersionAndUpdate(absJvmLocation, homeSubPath);
+    Pair<Pair<String, Boolean>, Pair<Version, Integer>> 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<String, Pair<Version, Integer>> getJDKNameVersionAndUpdate(File jvm, String homeSubPath) {
+  private static Pair<Pair<String, Boolean>, Pair<Version, Integer>> 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<Version, Integer> versionAndUpdate = null;
+    List<String> 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() {
index 84f470b7ea9e3f9f9263fbbaa29d90cec512024b..cee75f9b92ef2806764012da70112bc1ad771970 100644 (file)
@@ -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