From 4fd5545485c1b147657bfe5afa231abb572eb244 Mon Sep 17 00:00:00 2001 From: ge0rdi Date: Wed, 15 Jul 2026 14:07:42 +0200 Subject: [PATCH 1/2] Fix "Open file location" getting stuck after Windows 11 update We will run InvokeCommand API on separate STA thread and pump messages while waiting for them to finish. Fixes #2303 Fixes #2321 Fixes #2375 --- Src/StartMenu/StartMenuDLL/MenuCommands.cpp | 48 ++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/Src/StartMenu/StartMenuDLL/MenuCommands.cpp b/Src/StartMenu/StartMenuDLL/MenuCommands.cpp index 613bd95a0..ed396aca9 100644 --- a/Src/StartMenu/StartMenuDLL/MenuCommands.cpp +++ b/Src/StartMenu/StartMenuDLL/MenuCommands.cpp @@ -24,6 +24,52 @@ #include #include #include +#include + +// Execute function on a separate STA thread while pumping messages on caller thread. +template +static auto ExecuteOnSTAThread(TFunc&& func) -> decltype(func()) +{ + using ReturnType = decltype(func()); + ReturnType result{}; + + std::thread worker([&func, &result]() mutable { + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + result = func(); + CoUninitialize(); + }); + + // Pump messages while waiting for the worker (dialog) to finish + while (true) + { + HANDLE hWorker = worker.native_handle(); + if (MsgWaitForMultipleObjects(1, &hWorker, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0) + break; + + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + PostQuitMessage((int)msg.wParam); + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + worker.join(); + + return result; +} + +// Wrapper for IContextMenu::InvokeCommand that runs on separate STA thread and pumps messages +static HRESULT InvokeCommandSafe(IContextMenu* pMenu, LPCMINVOKECOMMANDINFO pInfo) +{ + return ExecuteOnSTAThread([&]() { + return pMenu->InvokeCommand(pInfo); + }); +} static CString g_RenameText; static POINT g_RenamePos; @@ -3113,7 +3159,7 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p } else { - HRESULT hr=pInvokeMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info); + HRESULT hr=InvokeCommandSafe(pInvokeMenu,(LPCMINVOKECOMMANDINFO)&info); LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr); executeSuccess=SUCCEEDED(hr); } From 566bb81c7ecdbccee9b5415a0baf523c4f4b7dc6 Mon Sep 17 00:00:00 2001 From: ge0rdi Date: Wed, 15 Jul 2026 14:10:25 +0200 Subject: [PATCH 2/2] Fix "Explore" getting stuck after Windows 11 update --- Src/StartMenu/StartMenuDLL/MenuCommands.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Src/StartMenu/StartMenuDLL/MenuCommands.cpp b/Src/StartMenu/StartMenuDLL/MenuCommands.cpp index ed396aca9..ff85c70f1 100644 --- a/Src/StartMenu/StartMenuDLL/MenuCommands.cpp +++ b/Src/StartMenu/StartMenuDLL/MenuCommands.cpp @@ -71,6 +71,14 @@ static HRESULT InvokeCommandSafe(IContextMenu* pMenu, LPCMINVOKECOMMANDINFO pInf }); } +// Wrapper for SHOpenFolderAndSelectItems that runs on separate STA thread and pumps messages +static HRESULT SHOpenFolderAndSelectItemsSafe(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD dwFlags) +{ + return ExecuteOnSTAThread([=]() { + return SHOpenFolderAndSelectItems(pidlFolder, cidl, apidl, dwFlags); + }); +} + static CString g_RenameText; static POINT g_RenamePos; @@ -2917,7 +2925,7 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p } else { - SHOpenFolderAndSelectItems(pItemPidl1,0,NULL,0); + SHOpenFolderAndSelectItemsSafe(pItemPidl1,0,NULL,0); } res=0; }