Skip to content

Commit

Permalink
Restart explorer "official" way
Browse files Browse the repository at this point in the history
  • Loading branch information
DartVanya committed Dec 10, 2024
1 parent a6aea48 commit ef06557
Showing 1 changed file with 73 additions and 24 deletions.
97 changes: 73 additions & 24 deletions SystemInformer/actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2281,6 +2281,7 @@ BOOLEAN PhUiRestartProcess(
BOOLEAN environmentAllocated = FALSE;
PVOID environmentBuffer = NULL;
ULONG environmentLength;
BOOLEAN processTerminated = FALSE;

if (PhGetIntegerSetting(L"EnableWarnings"))
{
Expand All @@ -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)))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.

Expand Down

0 comments on commit ef06557

Please sign in to comment.