mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-24 04:12:32 +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-->
|
||||
<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" />
|
||||
</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_impl.h" />
|
||||
<ClInclude Include="notifications.h" />
|
||||
<ClInclude Include="RestartManagement.h" />
|
||||
<ClInclude Include="shared_constants.h" />
|
||||
<ClInclude Include="timeutil.h" />
|
||||
<ClInclude Include="two_way_pipe_message_ipc.h" />
|
||||
@ -161,6 +162,7 @@
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RestartManagement.cpp" />
|
||||
<ClCompile Include="settings_helpers.cpp" />
|
||||
<ClCompile Include="settings_objects.cpp" />
|
||||
<ClCompile Include="icon_helpers.cpp" />
|
||||
|
@ -111,6 +111,9 @@
|
||||
<ClInclude Include="two_way_pipe_message_ipc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RestartManagement.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d2d_svg.cpp">
|
||||
@ -180,6 +183,9 @@
|
||||
<ClCompile Include="two_way_pipe_message_ipc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RestartManagement.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
@ -11,11 +11,10 @@
|
||||
|
||||
#include <common/common.h>
|
||||
#include <common/dpi_aware.h>
|
||||
|
||||
#include <common/winstore.h>
|
||||
#include <common/notifications.h>
|
||||
|
||||
#include <common/updating/updating.h>
|
||||
#include <common/RestartManagement.h>
|
||||
|
||||
#include "update_state.h"
|
||||
#include "update_utils.h"
|
||||
@ -23,6 +22,9 @@
|
||||
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
#include <Psapi.h>
|
||||
#include <RestartManager.h>
|
||||
|
||||
#if _DEBUG && _WIN64
|
||||
#include "unhandled_exception_handler.h"
|
||||
#endif
|
||||
@ -30,10 +32,16 @@
|
||||
|
||||
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
|
||||
{
|
||||
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 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
|
||||
@ -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)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
@ -273,7 +292,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
return 0;
|
||||
}
|
||||
case SpecialMode::ReportSuccessfulUpdate:
|
||||
notifications::show_toast(GET_RESOURCE_STRING(IDS_AUTOUPDATE_SUCCESS));
|
||||
RequestExplorerRestart();
|
||||
break;
|
||||
|
||||
case SpecialMode::None:
|
||||
|
@ -69,7 +69,7 @@
|
||||
<Link>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalDependencies>Msi.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Msi.lib;WindowsApp.lib;Rstrtmgr.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||
@ -93,7 +93,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalDependencies>Msi.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Msi.lib;WindowsApp.lib;Rstrtmgr.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||
|
Loading…
Reference in New Issue
Block a user