mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 09:28:03 +08:00
[Installer] Restart explorer.exe programatically after successful update (#4215)
* Restart explorer.exe programatically after successful update * Move RestartManager related code into common * Add newline at the end of files * Note that explorer.exe should not be localized string
This commit is contained in:
parent
d76234c112
commit
b0a25f59d9
@ -204,10 +204,6 @@
|
|||||||
|
|
||||||
<!-- Close 'PowerToys.exe' before uninstall-->
|
<!-- Close 'PowerToys.exe' before uninstall-->
|
||||||
<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable" />
|
<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable" />
|
||||||
<!-- Restart explorer.exe if we detect existing PowerRenameExt.dll or ImageResizerExt.dll installation -->
|
|
||||||
<util:CloseApplication Target="explorer.exe" RebootPrompt="no" TerminateProcess="0">
|
|
||||||
EXISTINGPOWERRENAMEEXTPATH OR EXISTINGIMAGERESIZERPATH
|
|
||||||
</util:CloseApplication>
|
|
||||||
<util:CloseApplication CloseMessage="yes" Target="PowerToys.exe" ElevatedCloseMessage="yes" RebootPrompt="no" TerminateProcess="0" />
|
<util:CloseApplication CloseMessage="yes" Target="PowerToys.exe" ElevatedCloseMessage="yes" RebootPrompt="no" TerminateProcess="0" />
|
||||||
</Product>
|
</Product>
|
||||||
|
|
||||||
|
64
src/common/RestartManagement.cpp
Normal file
64
src/common/RestartManagement.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "RestartManagement.h"
|
||||||
|
|
||||||
|
#include <RestartManager.h>
|
||||||
|
#include <Psapi.h>
|
||||||
|
|
||||||
|
std::vector<RM_UNIQUE_PROCESS> GetProcessInfoByName(const std::wstring& processName)
|
||||||
|
{
|
||||||
|
DWORD bytesReturned{};
|
||||||
|
std::vector<DWORD> processIds{};
|
||||||
|
processIds.resize(1024);
|
||||||
|
DWORD processIdSize{ (DWORD)processIds.size() * sizeof(DWORD) };
|
||||||
|
EnumProcesses(processIds.data(), processIdSize, &bytesReturned);
|
||||||
|
while (bytesReturned == processIdSize)
|
||||||
|
{
|
||||||
|
processIdSize *= 2;
|
||||||
|
processIds.resize(processIdSize / sizeof(DWORD));
|
||||||
|
EnumProcesses(processIds.data(), processIdSize, &bytesReturned);
|
||||||
|
}
|
||||||
|
std::vector<RM_UNIQUE_PROCESS> pInfos{};
|
||||||
|
for (const DWORD& processId : processIds)
|
||||||
|
{
|
||||||
|
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
||||||
|
if (hProcess)
|
||||||
|
{
|
||||||
|
wchar_t name[MAX_PATH];
|
||||||
|
if (GetProcessImageFileName(hProcess, name, MAX_PATH) > 0)
|
||||||
|
{
|
||||||
|
if (processName == PathFindFileName(name))
|
||||||
|
{
|
||||||
|
FILETIME creationTime{};
|
||||||
|
FILETIME exitTime{};
|
||||||
|
FILETIME kernelTime{};
|
||||||
|
FILETIME userTime{};
|
||||||
|
if (GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime))
|
||||||
|
{
|
||||||
|
pInfos.push_back({ processId, creationTime });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestartProcess(const std::wstring& processName)
|
||||||
|
{
|
||||||
|
DWORD sessionHandle{};
|
||||||
|
WCHAR sessionKey[CCH_RM_SESSION_KEY + 1];
|
||||||
|
if (RmStartSession(&sessionHandle, 0, sessionKey) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<RM_UNIQUE_PROCESS> pInfo = GetProcessInfoByName(processName);
|
||||||
|
if (pInfo.empty() ||
|
||||||
|
RmRegisterResources(sessionHandle, 0, nullptr, sizeof(pInfo), pInfo.data(), 0, nullptr) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RmShutdown(sessionHandle, RmForceShutdown, nullptr);
|
||||||
|
RmRestart(sessionHandle, 0, nullptr);
|
||||||
|
RmEndSession(sessionHandle);
|
||||||
|
}
|
5
src/common/RestartManagement.h
Normal file
5
src/common/RestartManagement.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void RestartProcess(const std::wstring& processName);
|
@ -125,6 +125,7 @@
|
|||||||
<ClInclude Include="keyboard_layout.h" />
|
<ClInclude Include="keyboard_layout.h" />
|
||||||
<ClInclude Include="keyboard_layout_impl.h" />
|
<ClInclude Include="keyboard_layout_impl.h" />
|
||||||
<ClInclude Include="notifications.h" />
|
<ClInclude Include="notifications.h" />
|
||||||
|
<ClInclude Include="RestartManagement.h" />
|
||||||
<ClInclude Include="shared_constants.h" />
|
<ClInclude Include="shared_constants.h" />
|
||||||
<ClInclude Include="timeutil.h" />
|
<ClInclude Include="timeutil.h" />
|
||||||
<ClInclude Include="two_way_pipe_message_ipc.h" />
|
<ClInclude Include="two_way_pipe_message_ipc.h" />
|
||||||
@ -161,6 +162,7 @@
|
|||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="RestartManagement.cpp" />
|
||||||
<ClCompile Include="settings_helpers.cpp" />
|
<ClCompile Include="settings_helpers.cpp" />
|
||||||
<ClCompile Include="settings_objects.cpp" />
|
<ClCompile Include="settings_objects.cpp" />
|
||||||
<ClCompile Include="icon_helpers.cpp" />
|
<ClCompile Include="icon_helpers.cpp" />
|
||||||
|
@ -111,6 +111,9 @@
|
|||||||
<ClInclude Include="two_way_pipe_message_ipc.h">
|
<ClInclude Include="two_way_pipe_message_ipc.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="RestartManagement.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="d2d_svg.cpp">
|
<ClCompile Include="d2d_svg.cpp">
|
||||||
@ -180,6 +183,9 @@
|
|||||||
<ClCompile Include="two_way_pipe_message_ipc.cpp">
|
<ClCompile Include="two_way_pipe_message_ipc.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="RestartManagement.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
@ -11,11 +11,10 @@
|
|||||||
|
|
||||||
#include <common/common.h>
|
#include <common/common.h>
|
||||||
#include <common/dpi_aware.h>
|
#include <common/dpi_aware.h>
|
||||||
|
|
||||||
#include <common/winstore.h>
|
#include <common/winstore.h>
|
||||||
#include <common/notifications.h>
|
#include <common/notifications.h>
|
||||||
|
|
||||||
#include <common/updating/updating.h>
|
#include <common/updating/updating.h>
|
||||||
|
#include <common/RestartManagement.h>
|
||||||
|
|
||||||
#include "update_state.h"
|
#include "update_state.h"
|
||||||
#include "update_utils.h"
|
#include "update_utils.h"
|
||||||
@ -23,6 +22,9 @@
|
|||||||
|
|
||||||
#include <winrt/Windows.System.h>
|
#include <winrt/Windows.System.h>
|
||||||
|
|
||||||
|
#include <Psapi.h>
|
||||||
|
#include <RestartManager.h>
|
||||||
|
|
||||||
#if _DEBUG && _WIN64
|
#if _DEBUG && _WIN64
|
||||||
#include "unhandled_exception_handler.h"
|
#include "unhandled_exception_handler.h"
|
||||||
#endif
|
#endif
|
||||||
@ -30,10 +32,16 @@
|
|||||||
|
|
||||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
|
// Window Explorer process name should not be localized.
|
||||||
|
const wchar_t EXPLORER_PROCESS_NAME[] = L"explorer.exe";
|
||||||
|
|
||||||
namespace localized_strings
|
namespace localized_strings
|
||||||
{
|
{
|
||||||
const wchar_t MSI_VERSION_IS_ALREADY_RUNNING[] = L"An older version of PowerToys is already running.";
|
const wchar_t MSI_VERSION_IS_ALREADY_RUNNING[] = L"An older version of PowerToys is already running.";
|
||||||
const wchar_t OLDER_MSIX_UNINSTALLED[] = L"An older MSIX version of PowerToys was uninstalled.";
|
const wchar_t OLDER_MSIX_UNINSTALLED[] = L"An older MSIX version of PowerToys was uninstalled.";
|
||||||
|
const wchar_t PT_UPDATE_MESSAGE_BOX_TITLE[] = L"PowerToys";
|
||||||
|
const wchar_t PT_UPDATE_MESSAGE_BOX_TEXT[] = L"PowerToys was updated and some components require Windows Explorer to restart. Do you want to restart Windows Explorer now?";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -249,6 +257,17 @@ toast_notification_handler_result toast_notification_handler(const std::wstring_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestExplorerRestart()
|
||||||
|
{
|
||||||
|
if (MessageBox(nullptr,
|
||||||
|
localized_strings::PT_UPDATE_MESSAGE_BOX_TEXT,
|
||||||
|
localized_strings::PT_UPDATE_MESSAGE_BOX_TITLE,
|
||||||
|
MB_ICONINFORMATION | MB_YESNO | MB_DEFBUTTON1) == IDYES)
|
||||||
|
{
|
||||||
|
RestartProcess(localized_strings::EXPLORER_PROCESS_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
winrt::init_apartment();
|
winrt::init_apartment();
|
||||||
@ -273,7 +292,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SpecialMode::ReportSuccessfulUpdate:
|
case SpecialMode::ReportSuccessfulUpdate:
|
||||||
notifications::show_toast(GET_RESOURCE_STRING(IDS_AUTOUPDATE_SUCCESS));
|
RequestExplorerRestart();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SpecialMode::None:
|
case SpecialMode::None:
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
<AdditionalDependencies>Msi.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>Msi.lib;WindowsApp.lib;Rstrtmgr.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||||
@ -93,7 +93,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
<AdditionalDependencies>Msi.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>Msi.lib;WindowsApp.lib;Rstrtmgr.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||||
|
Loading…
Reference in New Issue
Block a user