diff --git a/bin/restarter.exe b/bin/restarter.exe new file mode 100644 index 000000000000..013a91532625 Binary files /dev/null and b/bin/restarter.exe differ diff --git a/idea-tests/src/com/intellij/mock/MockApplication.java b/idea-tests/src/com/intellij/mock/MockApplication.java index 35e106095d47..ef42273161c5 100644 --- a/idea-tests/src/com/intellij/mock/MockApplication.java +++ b/idea-tests/src/com/intellij/mock/MockApplication.java @@ -103,6 +103,12 @@ public class MockApplication extends MockComponentManager implements Application return false; } + public boolean isRestartCapable() { + return false; + } + + public void restart() { + } public void runReadAction(Runnable action) { action.run(); diff --git a/platform-api/src/com/intellij/openapi/application/Application.java b/platform-api/src/com/intellij/openapi/application/Application.java index 173ccb32b7cc..ad9c8b6774e7 100644 --- a/platform-api/src/com/intellij/openapi/application/Application.java +++ b/platform-api/src/com/intellij/openapi/application/Application.java @@ -281,4 +281,15 @@ public interface Application extends ComponentManager { */ boolean isDisposeInProgress(); + /** + * Checks if IDEA is capable of restarting itself on the current platform and with the current execution mode. + * + * @return true if IDEA can restart itself, false otherwise. + */ + boolean isRestartCapable(); + + /** + * Exits and restarts IDEA. If the current platform is not restart capable, only exits. + */ + void restart(); } diff --git a/platform-impl/src/com/intellij/internal/RestartInfoAction.java b/platform-impl/src/com/intellij/internal/RestartInfoAction.java new file mode 100644 index 000000000000..34ed84b76600 --- /dev/null +++ b/platform-impl/src/com/intellij/internal/RestartInfoAction.java @@ -0,0 +1,18 @@ +package com.intellij.internal; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; + +/** + * @author yole + */ +public class RestartInfoAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final Application app = ApplicationManager.getApplication(); + if (app.isRestartCapable()) { + app.restart(); + } + } +} diff --git a/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 7f4e21f7f6f3..a9131a4dfbe0 100644 --- a/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -35,7 +35,6 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.ex.MessagesEx; import com.intellij.openapi.util.*; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.psi.PsiLock; @@ -972,6 +971,16 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application return myDisposeInProgress; } + public boolean isRestartCapable() { + return SystemInfo.isWindows; + } + + public void restart() { + if (SystemInfo.isWindows) { + Win32Restarter.restart(); + } + } + public boolean isSaving() { if (getStateStore().isSaving()) return true; Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); diff --git a/platform-impl/src/com/intellij/openapi/application/impl/Win32Restarter.java b/platform-impl/src/com/intellij/openapi/application/impl/Win32Restarter.java new file mode 100644 index 000000000000..3a38ee2a6d43 --- /dev/null +++ b/platform-impl/src/com/intellij/openapi/application/impl/Win32Restarter.java @@ -0,0 +1,44 @@ +package com.intellij.openapi.application.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.ui.Messages; +import com.sun.jna.Native; +import com.sun.jna.WString; +import com.sun.jna.win32.StdCallLibrary; + +import java.io.IOException; + +/** + * @author yole + */ +public class Win32Restarter { + private Win32Restarter() { + } + + public static void restart() { + Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); + WString cline = kernel32.GetCommandLineW(); + int pid = kernel32.GetCurrentProcessId(); + + try { + Runtime.getRuntime().exec("restarter " + Integer.toString(pid) + " " + cline); + } + catch (IOException ex) { + Messages.showMessageDialog("Restart failed: " + ex.getMessage(), "Restart", Messages.getErrorIcon()); + return; + } + try { + Thread.sleep(500); + } + catch (InterruptedException e1) { + // ignore + } + ((ApplicationEx)ApplicationManager.getApplication()).exit(true); + } + + private interface Kernel32 extends StdCallLibrary { + WString GetCommandLineW(); + int GetCurrentProcessId(); + } +} diff --git a/platform-resources/src/idea/PlatformActions.xml b/platform-resources/src/idea/PlatformActions.xml index dfe4e6ba48cf..f30075dbf9c4 100644 --- a/platform-resources/src/idea/PlatformActions.xml +++ b/platform-resources/src/idea/PlatformActions.xml @@ -376,6 +376,7 @@ + diff --git a/tools/restarter/ReadMe.txt b/tools/restarter/ReadMe.txt new file mode 100644 index 000000000000..80a9a1c63148 --- /dev/null +++ b/tools/restarter/ReadMe.txt @@ -0,0 +1,33 @@ +======================================================================== + CONSOLE APPLICATION : restarter Project Overview +======================================================================== + +AppWizard has created this restarter application for you. + +This file contains a summary of what you will find in each of the files that +make up your restarter application. + + +restarter.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +restarter.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named restarter.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/tools/restarter/restarter.cpp b/tools/restarter/restarter.cpp new file mode 100644 index 000000000000..81c4a6a2568b --- /dev/null +++ b/tools/restarter/restarter.cpp @@ -0,0 +1,24 @@ +// restarter.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ + if (argc < 3) return 0; + int ppid = _ttoi(argv [1]); + HANDLE parent_process = OpenProcess(SYNCHRONIZE, FALSE, ppid); + if (!parent_process) return 0; + WaitForSingleObject(parent_process, INFINITE); + CloseHandle(parent_process); + + int rc = _texecv(argv [2], argv+3); + if (rc == -1) + { + _tprintf(_T("Error restarting process: errno is %d"), errno); + } + + return 0; +} + diff --git a/tools/restarter/restarter.sln b/tools/restarter/restarter.sln new file mode 100644 index 000000000000..359e70e11595 --- /dev/null +++ b/tools/restarter/restarter.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "restarter", "restarter.vcproj", "{1B2485B2-CFED-4B2F-8FFD-00F1C9E1BD0C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B2485B2-CFED-4B2F-8FFD-00F1C9E1BD0C}.Debug|Win32.ActiveCfg = Debug|Win32 + {1B2485B2-CFED-4B2F-8FFD-00F1C9E1BD0C}.Debug|Win32.Build.0 = Debug|Win32 + {1B2485B2-CFED-4B2F-8FFD-00F1C9E1BD0C}.Release|Win32.ActiveCfg = Release|Win32 + {1B2485B2-CFED-4B2F-8FFD-00F1C9E1BD0C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/restarter/restarter.vcproj b/tools/restarter/restarter.vcproj new file mode 100644 index 000000000000..35a37bcc531e --- /dev/null +++ b/tools/restarter/restarter.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/restarter/stdafx.cpp b/tools/restarter/stdafx.cpp new file mode 100644 index 000000000000..ba19d2643788 --- /dev/null +++ b/tools/restarter/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// restarter.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/tools/restarter/stdafx.h b/tools/restarter/stdafx.h new file mode 100644 index 000000000000..661cb268562b --- /dev/null +++ b/tools/restarter/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/tools/restarter/targetver.h b/tools/restarter/targetver.h new file mode 100644 index 000000000000..6fe8eb79e1a1 --- /dev/null +++ b/tools/restarter/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif +