mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[platform] extracting IDE starter location code (IDEA-219946)
GitOrigin-RevId: 261c0499fb931cc55d53aedf532a6b618f3b5ec9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0445f1b573
commit
ad8272c32a
@@ -21,6 +21,7 @@ import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -74,9 +75,9 @@ public class WindowsDefenderChecker {
|
||||
RealtimeScanningStatus scanningStatus = getRealtimeScanningEnabled();
|
||||
if (scanningStatus == RealtimeScanningStatus.SCANNING_ENABLED) {
|
||||
final Collection<String> processes = getExcludedProcesses();
|
||||
final String binaryName = Restarter.getCurrentProcessExecutableName();
|
||||
if (binaryName != null && processes != null &&
|
||||
processes.contains(StringUtil.substringAfterLast(binaryName.toLowerCase(), "\\")) &&
|
||||
final File exe = Restarter.getIdeStarter();
|
||||
if (exe != null && processes != null &&
|
||||
processes.contains(exe.getName().toLowerCase(Locale.ENGLISH)) &&
|
||||
processes.contains("java.exe")) {
|
||||
return new CheckResult(RealtimeScanningStatus.SCANNING_DISABLED, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@@ -19,12 +19,11 @@ import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.updateSettings.impl.ExternalUpdateManager;
|
||||
import com.intellij.openapi.util.AtomicNullableLazyValue;
|
||||
import com.intellij.openapi.util.NullableLazyValue;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.AppUIUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.Restarter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -43,26 +42,6 @@ import static com.intellij.util.containers.ContainerUtil.newHashMap;
|
||||
public class CreateDesktopEntryAction extends DumbAwareAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CreateDesktopEntryAction");
|
||||
|
||||
private static final NullableLazyValue<String> ourScript = new AtomicNullableLazyValue<String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
protected String compute() {
|
||||
String binPath = PathManager.getBinPath();
|
||||
ApplicationNamesInfo names = ApplicationNamesInfo.getInstance();
|
||||
|
||||
String execPath = binPath + '/' + names.getProductName() + ".sh";
|
||||
if (new File(execPath).canExecute()) return execPath;
|
||||
|
||||
execPath = binPath + '/' + StringUtil.toLowerCase(names.getProductName()) + ".sh";
|
||||
if (new File(execPath).canExecute()) return execPath;
|
||||
|
||||
execPath = binPath + '/' + names.getScriptName() + ".sh";
|
||||
if (new File(execPath).canExecute()) return execPath;
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public static boolean isAvailable() {
|
||||
return SystemInfo.isXWindow && !ExternalUpdateManager.isRoaming() && SystemInfo.hasXdgOpen();
|
||||
}
|
||||
@@ -140,11 +119,11 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
|
||||
throw new RuntimeException(ApplicationBundle.message("desktop.entry.icon.missing", binPath));
|
||||
}
|
||||
|
||||
String execPath = ourScript.getValue();
|
||||
if (execPath == null) {
|
||||
File starter = Restarter.getIdeStarter();
|
||||
if (starter == null) {
|
||||
throw new RuntimeException(ApplicationBundle.message("desktop.entry.script.missing", binPath));
|
||||
}
|
||||
execPath = StringUtil.wrapWithDoubleQuote(execPath);
|
||||
String execPath = StringUtil.wrapWithDoubleQuote(starter.getPath());
|
||||
|
||||
ApplicationNamesInfo names = ApplicationNamesInfo.getInstance();
|
||||
|
||||
@@ -210,9 +189,4 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
|
||||
return myContentPane;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getLauncherScript() {
|
||||
return ourScript.getValue();
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.Restarter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -160,8 +161,8 @@ public class CreateLauncherScriptAction extends DumbAwareAction {
|
||||
}
|
||||
|
||||
private static File createLauncherScriptFile() throws IOException, ExecutionException {
|
||||
String runPath = SystemInfo.isMac ? StringUtil.trimEnd(PathManager.getHomePath(), "/Contents") : CreateDesktopEntryAction.getLauncherScript();
|
||||
if (runPath == null) throw new IOException(ApplicationBundle.message("desktop.entry.script.missing", PathManager.getBinPath()));
|
||||
File starter = Restarter.getIdeStarter();
|
||||
if (starter == null) throw new IOException(ApplicationBundle.message("desktop.entry.script.missing", PathManager.getBinPath()));
|
||||
|
||||
ClassLoader loader = CreateLauncherScriptAction.class.getClassLoader();
|
||||
assert loader != null;
|
||||
@@ -169,7 +170,7 @@ public class CreateLauncherScriptAction extends DumbAwareAction {
|
||||
pair("$PYTHON$", INTERPRETER_NAME.getValue()),
|
||||
pair("$CONFIG_PATH$", PathManager.getConfigPath()),
|
||||
pair("$SYSTEM_PATH$", PathManager.getSystemPath()),
|
||||
pair("$RUN_PATH$", runPath));
|
||||
pair("$RUN_PATH$", starter.getPath()));
|
||||
String launcherContents = StringUtil.convertLineSeparators(ExecUtil.loadTemplate(loader, "launcher.py", variables));
|
||||
|
||||
return ExecUtil.createTempExecutableScript("launcher", "", launcherContents);
|
||||
|
||||
@@ -4,14 +4,16 @@ package com.intellij.util;
|
||||
import com.intellij.execution.configurations.PathEnvironmentVariableUtil;
|
||||
import com.intellij.execution.process.UnixProcessManager;
|
||||
import com.intellij.execution.process.WinProcessManager;
|
||||
import com.intellij.ide.actions.CreateDesktopEntryAction;
|
||||
import com.intellij.jna.JnaLoader;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.updateSettings.impl.UpdateInstaller;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.NullableLazyValue;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.WString;
|
||||
@@ -19,6 +21,7 @@ import com.sun.jna.platform.win32.WinDef;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.win32.StdCallLibrary;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -47,12 +50,15 @@ public class Restarter {
|
||||
if (!JnaLoader.isLoaded()) {
|
||||
problem = "JNA not loaded";
|
||||
}
|
||||
else if (ourStarter.getValue() == null) {
|
||||
problem = "GetModuleFileName() failed";
|
||||
}
|
||||
else {
|
||||
problem = checkRestarter("restarter.exe");
|
||||
}
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
if (getMacOsAppDir() == null) {
|
||||
if (ourStarter.getValue() == null) {
|
||||
problem = "not a bundle: " + PathManager.getHomePath();
|
||||
}
|
||||
else {
|
||||
@@ -63,7 +69,7 @@ public class Restarter {
|
||||
if (UnixProcessManager.getCurrentProcessId() <= 0) {
|
||||
problem = "cannot detect process ID";
|
||||
}
|
||||
else if (CreateDesktopEntryAction.getLauncherScript() == null) {
|
||||
else if (ourStarter.getValue() == null) {
|
||||
problem = "cannot find launcher script in " + PathManager.getBinPath();
|
||||
}
|
||||
else if (PathEnvironmentVariableUtil.findInPath("python") == null && PathEnvironmentVariableUtil.findInPath("python3") == null) {
|
||||
@@ -107,6 +113,38 @@ public class Restarter {
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable File getIdeStarter() {
|
||||
return ourStarter.getValue();
|
||||
}
|
||||
|
||||
private static final NullableLazyValue<File> ourStarter = new NullableLazyValue<File>() {
|
||||
@Override
|
||||
protected File compute() {
|
||||
if (SystemInfo.isWindows && JnaLoader.isLoaded()) {
|
||||
Kernel32 kernel32 = Native.load("kernel32", Kernel32.class);
|
||||
char[] buffer = new char[32767]; // using 32,767 as buffer size to avoid limiting ourselves to MAX_PATH (260)
|
||||
int result = kernel32.GetModuleFileNameW(null, buffer, new WinDef.DWORD(buffer.length)).intValue();
|
||||
if (result != 0) return new File(Native.toString(buffer));
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
File appDir = new File(PathManager.getHomePath()).getParentFile();
|
||||
if (appDir != null && appDir.getName().endsWith(".app") && appDir.isDirectory()) return appDir;
|
||||
}
|
||||
else if (SystemInfo.isUnix) {
|
||||
String binPath = PathManager.getBinPath();
|
||||
ApplicationNamesInfo names = ApplicationNamesInfo.getInstance();
|
||||
File starter = new File(binPath, names.getProductName() + ".sh");
|
||||
if (starter.canExecute()) return starter;
|
||||
starter = new File(binPath, StringUtil.toLowerCase(names.getProductName()) + ".sh");
|
||||
if (starter.canExecute()) return starter;
|
||||
starter = new File(binPath, names.getScriptName() + ".sh");
|
||||
if (starter.canExecute()) return starter;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
private static void restartOnWindows(boolean elevate, String... beforeRestart) throws IOException {
|
||||
Kernel32 kernel32 = Native.load("kernel32", Kernel32.class);
|
||||
Shell32 shell32 = Native.load("shell32", Shell32.class);
|
||||
@@ -118,12 +156,10 @@ public class Restarter {
|
||||
kernel32.LocalFree(argvPtr);
|
||||
|
||||
// See https://blogs.msdn.microsoft.com/oldnewthing/20060515-07/?p=31203
|
||||
// argv[0] as the program name is only a convention, i.e. there is no guarantee
|
||||
// the name is the full path to the executable.
|
||||
final String binaryName = getCurrentProcessExecutableName();
|
||||
if (binaryName != null) {
|
||||
argv[0] = binaryName;
|
||||
}
|
||||
// argv[0] as the program name is only a convention, i.e. there is no guarantee the name is the full path to the executable
|
||||
File starter = ourStarter.getValue();
|
||||
if (starter == null) throw new IOException("GetModuleFileName() failed");
|
||||
argv[0] = starter.getPath();
|
||||
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add(String.valueOf(pid));
|
||||
@@ -153,20 +189,6 @@ public class Restarter {
|
||||
TimeoutUtil.sleep(500);
|
||||
}
|
||||
|
||||
//
|
||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx
|
||||
// To retrieve the full path to the executable, use "GetModuleFileName(NULL, ...)".
|
||||
//
|
||||
// Note: We use 32,767 as buffer size to avoid limiting ourselves to MAX_PATH (260).
|
||||
public static String getCurrentProcessExecutableName() {
|
||||
Kernel32 kernel32 = Native.load("kernel32", Kernel32.class);
|
||||
char[] buffer = new char[32767];
|
||||
if (kernel32.GetModuleFileNameW(null, buffer, new WinDef.DWORD(buffer.length)).intValue() > 0) {
|
||||
return Native.toString(buffer);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String[] getRestartArgv(String[] argv) {
|
||||
String mainClass = System.getProperty("idea.main.class.name", "com.intellij.idea.Main");
|
||||
|
||||
@@ -188,7 +210,7 @@ public class Restarter {
|
||||
}
|
||||
|
||||
private static void restartOnMac(String... beforeRestart) throws IOException {
|
||||
File appDir = getMacOsAppDir();
|
||||
File appDir = ourStarter.getValue();
|
||||
if (appDir == null) throw new IOException("Application bundle not found: " + PathManager.getHomePath());
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add(appDir.getPath());
|
||||
@@ -196,14 +218,9 @@ public class Restarter {
|
||||
runRestarter(new File(PathManager.getBinPath(), "restarter"), args);
|
||||
}
|
||||
|
||||
private static File getMacOsAppDir() {
|
||||
File appDir = new File(PathManager.getHomePath()).getParentFile();
|
||||
return appDir != null && appDir.getName().endsWith(".app") && appDir.isDirectory() ? appDir : null;
|
||||
}
|
||||
|
||||
private static void restartOnUnix(String... beforeRestart) throws IOException {
|
||||
String launcherScript = CreateDesktopEntryAction.getLauncherScript();
|
||||
if (launcherScript == null) throw new IOException("Launcher script not found in " + PathManager.getBinPath());
|
||||
File starterScript = ourStarter.getValue();
|
||||
if (starterScript == null) throw new IOException("Starter script not found in " + PathManager.getBinPath());
|
||||
|
||||
int pid = UnixProcessManager.getCurrentProcessId();
|
||||
if (pid <= 0) throw new IOException("Invalid process ID: " + pid);
|
||||
@@ -216,14 +233,14 @@ public class Restarter {
|
||||
List<String> args = new ArrayList<>();
|
||||
if ("python".equals(python.getName())) {
|
||||
args.add(String.valueOf(pid));
|
||||
args.add(launcherScript);
|
||||
args.add(starterScript.getPath());
|
||||
Collections.addAll(args, beforeRestart);
|
||||
runRestarter(script, args);
|
||||
}
|
||||
else {
|
||||
args.add(script.getPath());
|
||||
args.add(String.valueOf(pid));
|
||||
args.add(launcherScript);
|
||||
args.add(starterScript.getPath());
|
||||
Collections.addAll(args, beforeRestart);
|
||||
runRestarter(python, args);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user