From e21ee3835347b042103d698b1a75681e073d3b08 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 12 Jan 2009 14:56:29 +0300 Subject: [PATCH] initial implementation of IDEA restarter for Win32 --- bin/restarter.exe | Bin 0 -> 7680 bytes .../com/intellij/mock/MockApplication.java | 6 + .../openapi/application/Application.java | 11 + .../intellij/internal/RestartInfoAction.java | 18 ++ .../application/impl/ApplicationImpl.java | 11 +- .../application/impl/Win32Restarter.java | 44 ++++ .../src/idea/PlatformActions.xml | 1 + tools/restarter/ReadMe.txt | 33 +++ tools/restarter/restarter.cpp | 24 ++ tools/restarter/restarter.sln | 20 ++ tools/restarter/restarter.vcproj | 225 ++++++++++++++++++ tools/restarter/stdafx.cpp | 8 + tools/restarter/stdafx.h | 16 ++ tools/restarter/targetver.h | 13 + 14 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 bin/restarter.exe create mode 100644 platform-impl/src/com/intellij/internal/RestartInfoAction.java create mode 100644 platform-impl/src/com/intellij/openapi/application/impl/Win32Restarter.java create mode 100644 tools/restarter/ReadMe.txt create mode 100644 tools/restarter/restarter.cpp create mode 100644 tools/restarter/restarter.sln create mode 100644 tools/restarter/restarter.vcproj create mode 100644 tools/restarter/stdafx.cpp create mode 100644 tools/restarter/stdafx.h create mode 100644 tools/restarter/targetver.h diff --git a/bin/restarter.exe b/bin/restarter.exe new file mode 100644 index 0000000000000000000000000000000000000000..013a915326257daa8ee66fdafbc15c82752b0368 GIT binary patch literal 7680 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 V!av5ZvRmyQd%u0a4voL5_B%*P_p<;1 literal 0 HcmV?d00001 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 +