From ef065573b2d55f1155b0a9b1ca7e699ef5215e75 Mon Sep 17 00:00:00 2001 From: Dart Vanya Date: Tue, 10 Dec 2024 03:02:20 +0300 Subject: [PATCH 1/2] Restart explorer "official" way --- SystemInformer/actions.c | 97 ++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 24 deletions(-) diff --git a/SystemInformer/actions.c b/SystemInformer/actions.c index f9f81c8043b8..d7c07cab9d78 100644 --- a/SystemInformer/actions.c +++ b/SystemInformer/actions.c @@ -2281,6 +2281,7 @@ BOOLEAN PhUiRestartProcess( BOOLEAN environmentAllocated = FALSE; PVOID environmentBuffer = NULL; ULONG environmentLength; + BOOLEAN processTerminated = FALSE; if (PhGetIntegerSetting(L"EnableWarnings")) { @@ -2306,29 +2307,6 @@ BOOLEAN PhUiRestartProcess( if (Process->ProcessId == NtCurrentProcessId()) return FALSE; - // Special handling for the current shell process. (dmex) - { - CLIENT_ID shellClientId; - - if (NT_SUCCESS(PhGetWindowClientId(PhGetShellWindow(), &shellClientId))) - { - if (Process->ProcessId == shellClientId.UniqueProcess) - { - status = PhOpenProcess( - &processHandle, - PROCESS_TERMINATE, - Process->ProcessId - ); - - if (NT_SUCCESS(status)) - { - PhTerminateProcess(processHandle, STATUS_SUCCESS); - NtClose(processHandle); - } - } - } - } - fileNameWin32 = Process->FileName ? PhGetFileName(Process->FileName) : NULL; if (PhIsNullOrEmptyString(fileNameWin32) || !PhDoesFileExistWin32(PhGetString(fileNameWin32))) @@ -2370,6 +2348,74 @@ BOOLEAN PhUiRestartProcess( NtClose(processHandle); processHandle = NULL; + // Special handling for the current shell process. (dmex) + // Handling shell process only after VM_READ routines above have completed, because we cannot properly read memory of exited process (Dart Vanya) + { + CLIENT_ID shellClientId; + HWND shellWindow; + + if (NT_SUCCESS(PhGetWindowClientId(shellWindow = PhGetShellWindow(), &shellClientId)) && + Process->ProcessId == shellClientId.UniqueProcess) + { + if (NT_SUCCESS(PhOpenProcess( + &processHandle, + SYNCHRONIZE, + Process->ProcessId + ))) + { + BOOLEAN postToTaskbar = WindowsVersion >= WINDOWS_VISTA; + + if (postToTaskbar) + { + HWND taskbarWindow = NULL; + CLIENT_ID taskbarClientId; + WCHAR windowClassName[MAX_PATH] = L""; + + while (taskbarWindow = FindWindowEx(NULL, taskbarWindow, NULL, NULL)) + { + if (NT_SUCCESS(PhGetWindowClientId(taskbarWindow, &taskbarClientId)) && + taskbarClientId.UniqueProcess == shellClientId.UniqueProcess) + { + GetClassName(taskbarWindow, windowClassName, RTL_NUMBER_OF(windowClassName)); + if (PhEqualStringZ(windowClassName, L"Shell_TrayWnd", FALSE)) + { + postToTaskbar = !PostMessage(taskbarWindow, WM_USER + 0x1B4, 0, 0); // exit Explorer official way (Dart Vanya) + break; + } + } + } + } + + if (postToTaskbar) + { + PostMessage(shellWindow, WM_QUIT, 0, 0); + } + + // Wait for a reasonably timeout (maybe a setting like ExplorerShellRestartTimeout?) + status = PhWaitForMultipleObjectsAndPump(NULL, 1, &processHandle, 2500, QS_ALLINPUT); + processTerminated = status == STATUS_WAIT_0; + NtClose(processHandle); + processHandle = NULL; + + if (!processTerminated) + { + status = PhOpenProcess( + &processHandle, + PROCESS_TERMINATE, + Process->ProcessId + ); + + if (NT_SUCCESS(status)) + { + processTerminated = NT_SUCCESS(PhTerminateProcess(processHandle, STATUS_SUCCESS)); + NtClose(processHandle); + processHandle = NULL; + } + } + } + } + } + // Start the process. // // Use the existing process as the parent, and restarting the process will inherit most of the process configuration from itself (dmex) @@ -2541,7 +2587,10 @@ BOOLEAN PhUiRestartProcess( // Terminate the existing process. - PhTerminateProcess(processHandle, STATUS_SUCCESS); + if (!processTerminated) + { + status = PhTerminateProcess(processHandle, STATUS_SUCCESS); + } // Update the console foreground. From 4d251739e98df4052a892c9dac5a2fa36d7685d8 Mon Sep 17 00:00:00 2001 From: Dart Vanya Date: Tue, 10 Dec 2024 03:46:50 +0300 Subject: [PATCH 2/2] "Restart shell" menu name --- SystemInformer/mwpgproc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SystemInformer/mwpgproc.c b/SystemInformer/mwpgproc.c index ffc194e28c23..dc4cbc0604a4 100644 --- a/SystemInformer/mwpgproc.c +++ b/SystemInformer/mwpgproc.c @@ -851,6 +851,21 @@ VOID PhMwpInitializeProcessMenu( item->Flags |= PH_EMENU_DISABLED; } } + + // Special case for the current shell process + if (item = PhFindEMenuItem(Menu, 0, 0, ID_PROCESS_RESTART)) + { + if (NumberOfProcesses == 1) + { + CLIENT_ID shellClientId; + + if (NT_SUCCESS(PhGetWindowClientId(PhGetShellWindow(), &shellClientId)) && + Processes[0]->ProcessId == shellClientId.UniqueProcess) + { + item->Text = L"Res&tart shell"; + } + } + } } PPH_EMENU PhpCreateProcessMenu(