Compare commits

..
6 Commits
Author SHA1 Message Date
ge0rdi 8713a69200 Sign with SignPath
Fixes #1732
2026-07-15 14:25:37 +02:00
ge0rdi b264f96525 Split build steps into binaries, installers, archives 2026-07-15 14:25:37 +02:00
ge0rdi 07ead0baf8 Utility: Fix clash with windows API 2026-07-15 14:25:36 +02:00
ge0rdi 566bb81c7e Fix "Explore" getting stuck after Windows 11 update 2026-07-15 14:14:10 +02:00
ge0rdi 4fd5545485 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
2026-07-15 14:14:10 +02:00
ge0rdiandGitHub 86e8a24b16 [ExplorerPatcher] Improved EP taskbar detection (#2493)
EP changed their `ep_taskbar*.dll` naming scheme.
We will look for module whose name starts with `ep_taskbar` which
should be compatible with both old and new naming.

Fixes #2474
2026-07-15 14:12:25 +02:00
4 changed files with 93 additions and 9 deletions
+3 -3
View File
@@ -79,7 +79,7 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: 'b34b60e3-e5bf-4a6e-a13c-dcf641b4362c'
project-slug: 'Open-Shell-Menu'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'Binaries'
github-artifact-id: '${{ steps.upload-binaries.outputs.artifact-id }}'
wait-for-completion: true
@@ -108,7 +108,7 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: 'b34b60e3-e5bf-4a6e-a13c-dcf641b4362c'
project-slug: 'Open-Shell-Menu'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'Installers'
github-artifact-id: '${{ steps.upload-installers.outputs.artifact-id }}'
wait-for-completion: true
@@ -149,7 +149,7 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: 'b34b60e3-e5bf-4a6e-a13c-dcf641b4362c'
project-slug: 'Open-Shell-Menu'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
github-artifact-id: '${{ steps.upload-setup.outputs.artifact-id }}'
wait-for-completion: true
skip-decompress: true
+3
View File
@@ -23,6 +23,9 @@ You can find the latest stable version here:
[![GitHub All Releases](https://img.shields.io/github/downloads/Open-Shell/Open-Shell-Menu/total?style=for-the-badge&color=4bc2ee&logo=github)](https://github.com/Open-Shell/Open-Shell-Menu/releases/latest)
> [!NOTE]
> Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
> [!IMPORTANT]
> #### Windows for ARM compatibility
> Open-Shell is compatible with Windows for ARM since version [4.4.196](https://github.com/Open-Shell/Open-Shell-Menu/releases/tag/v4.4.196).
+56 -2
View File
@@ -24,6 +24,60 @@
#include <propvarutil.h>
#include <algorithm>
#include <propkey.h>
#include <thread>
// Execute function on a separate STA thread while pumping messages on caller thread.
template <typename TFunc>
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);
});
}
// 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;
@@ -2871,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;
}
@@ -3113,7 +3167,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);
}
+31 -4
View File
@@ -22,6 +22,7 @@
#include <dbghelp.h>
#include <set>
#include <Thumbcache.h>
#include <tlhelp32.h>
#define HOOK_DROPTARGET // define this to replace the IDropTarget of the start button
#define START_TOUCH // touch support for the start button
@@ -2936,6 +2937,35 @@ static void OpenCortana( void )
ShellExecute(NULL,NULL,L"shell:::{2559a1f8-21d7-11d4-bdaf-00c04f60b9f0}",NULL,NULL,SW_SHOWNORMAL);
}
HMODULE GetModuleHandleByPrefix(const WCHAR* prefix)
{
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if (snapshot == INVALID_HANDLE_VALUE)
return nullptr;
size_t prefixLength = wcslen(prefix);
MODULEENTRY32 me{};
me.dwSize = sizeof(me);
HMODULE result = nullptr;
if (Module32First(snapshot, &me))
{
do
{
if (_wcsnicmp(me.szModule, prefix, prefixLength) == 0)
{
result = reinterpret_cast<HMODULE>(me.modBaseAddr);
break;
}
} while (Module32Next(snapshot, &me));
}
CloseHandle(snapshot);
return result;
}
static void InitStartMenuDLL( void )
{
static bool initCalled = false;
@@ -2979,10 +3009,7 @@ static void InitStartMenuDLL( void )
auto module=GetModuleHandle(L"taskbar.dll");
if (!module)
{
module = GetModuleHandle(L"ep_taskbar.5.dll");
if (!module)
module = GetModuleHandle(L"ep_taskbar.2.dll");
module = GetModuleHandleByPrefix(L"ep_taskbar");
if (module)
g_epTaskbar = true;
}