Skip to content

Conversation

@DartVanya
Copy link
Contributor

No description provided.

@DartVanya DartVanya force-pushed the gentle-explorer-restart branch 2 times, most recently from b76692a to 449a089 Compare December 10, 2024 00:13
@DartVanya DartVanya force-pushed the gentle-explorer-restart branch from 449a089 to ef06557 Compare December 10, 2024 00:35
@dmex dmex self-requested a review January 7, 2025 16:08
@dmex dmex self-assigned this Jan 7, 2025
@dmex dmex added postponed Delayed until a dependency or issue is resolved Blocked Delayed until a dependency or issue is resolved labels Jan 7, 2025
@DartVanya DartVanya force-pushed the gentle-explorer-restart branch from aa74b5d to 046d4f3 Compare January 29, 2025 18:59
@DartVanya DartVanya force-pushed the gentle-explorer-restart branch from 046d4f3 to 00e05cc Compare January 29, 2025 19:00
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which OS are these values from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't send private window messages since the identifiers can change. The menu this references was removed on Windows 11.

@DartVanya DartVanya requested a review from dmex February 1, 2025 01:27
@jxy-s jxy-s self-requested a review as a code owner August 1, 2025 03:04
@dmex
Copy link
Collaborator

dmex commented Sep 23, 2025

Here's a fully documented and official method for restarting the Explorer process:

BOOL CALLBACK EnumWindowCallback(
    _In_ HWND WindowHandle,
    _In_ LPARAM Context
    )
{
    ULONG processId = 0;

    GetWindowThreadProcessId(WindowHandle, &processId);

    if (processId == (ULONG)Context && IsWindowVisible(WindowHandle))
    {
        ULONG_PTR result = 0;

        if (SendMessageTimeout(
            WindowHandle,
            WM_QUERYENDSESSION,
            0,
            ENDSESSION_CLOSEAPP,
            SMTO_ABORTIFHUNG | SMTO_BLOCK | SMTO_ERRORONEXIT,
            5000,
            &result
            ))
        {
            if (result)
            {
                SendMessageTimeout(
                    WindowHandle,
                    WM_ENDSESSION,
                    TRUE,
                    ENDSESSION_LOGOFF,
                    SMTO_ABORTIFHUNG | SMTO_BLOCK | SMTO_ERRORONEXIT,
                    5000,
                    &result
                    );
            }
        }
    }

    return TRUE;
}

VOID CloseExplorer()
{
    ULONG processId = 0;

    GetWindowThreadProcessId(GetShellWindow(), &processId);

    EnumWindows(EnumWindowCallback, (LPARAM)processId);
}

The Explorer process and desktop shell cleanup and exit cleanly. If there are multiple explorer.exe processes then you have to send these message to both processes. This code only sends the message to the shell window as an example showing it cleanup and exit successfully.

These messages and functions are documented and supported by Microsoft:
https://learn.microsoft.com/en-us/windows/win32/shutdown/wm-queryendsession
https://learn.microsoft.com/en-us/windows/win32/shutdown/wm-endsession
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagetimeoutw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Blocked Delayed until a dependency or issue is resolved postponed Delayed until a dependency or issue is resolved

2 participants