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 b76692a
Showing 1 changed file with 72 additions and 24 deletions.
96 changes: 72 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,73 @@ 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 = NULL;

if (NT_SUCCESS(PhGetWindowClientId(shellWindow = PhGetShellWindow(), &shellClientId)) &&
Process->ProcessId == shellClientId.UniqueProcess)
{
if (NT_SUCCESS(PhOpenProcess(
&processHandle,
SYNCHRONIZE,
Process->ProcessId
)))
{
if (WindowsVersion >= WINDOWS_VISTA)
{
CLIENT_ID taskbarClientId;
WCHAR windowClassName[MAX_PATH] = L"";
shellWindow = NULL;

while (shellWindow = FindWindowEx(NULL, shellWindow, NULL, NULL))
{
if (NT_SUCCESS(PhGetWindowClientId(shellWindow, &taskbarClientId)) &&
taskbarClientId.UniqueProcess == shellClientId.UniqueProcess)
{
GetClassName(WindowHandle, windowClassName, RTL_NUMBER_OF(windowClassName));

if (PhEqualStringZ(windowClassName, L"Shell_TrayWnd", FALSE))
{
PostMessage(shellWindow, WM_USER + 0x1B4, 0, 0); // exit Explorer official way (Dart Vanya)
break;
}
}
}
}
else
{
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 +2586,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 b76692a

Please sign in to comment.