[PATCH] Fix AS restart when started from command prompt (windows)
authorRenaud Paquay <rpaquay@google.com>
Mon, 5 Sep 2016 13:22:09 +0000 (16:22 +0300)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Mon, 5 Sep 2016 13:22:37 +0000 (16:22 +0300)
BUG=https://code.google.com/p/android/issues/detail?id=221499

platform/platform-impl/src/com/intellij/util/Restarter.java

index ccb9fdc102f54afe3004285c279246a77cd901d6..ea342f907445e3a041198dd0c00ac9f7cdd41f35 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.sun.jna.Native;
 import com.sun.jna.Pointer;
 import com.sun.jna.WString;
+import com.sun.jna.platform.win32.WinDef;
 import com.sun.jna.ptr.IntByReference;
 import com.sun.jna.win32.StdCallLibrary;
 import org.jetbrains.annotations.NotNull;
@@ -117,6 +118,19 @@ public class Restarter {
     final String[] argv = getRestartArgv(argv_ptr.getWideStringArray(0, argc.getValue()));
     kernel32.LocalFree(argv_ptr);
 
+    // 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.
+    //
+    // 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).
+    char[] buffer = new char[32767];
+    if (kernel32.GetModuleFileNameW(null, buffer, new WinDef.DWORD(buffer.length)).intValue() > 0) {
+      argv[0] = Native.toString(buffer);
+    }
+
     doScheduleRestart(new File(PathManager.getBinPath(), "restarter.exe"), commands -> {
       Collections.addAll(commands, String.valueOf(pid), String.valueOf(beforeRestart.length));
       Collections.addAll(commands, beforeRestart);
@@ -192,6 +206,8 @@ public class Restarter {
     WString GetCommandLineW();
 
     Pointer LocalFree(Pointer pointer);
+
+    WinDef.DWORD GetModuleFileNameW(WinDef.HMODULE hModule, char[] lpFilename, WinDef.DWORD nSize);
   }
 
   private interface Shell32 extends StdCallLibrary {