diff --git a/Src/Localization/English/StartMenu.html b/Src/Localization/English/StartMenu.html
index 1f966435a..72531e856 100644
--- a/Src/Localization/English/StartMenu.html
+++ b/Src/Localization/English/StartMenu.html
@@ -120,7 +120,7 @@
Operation
Right-click on an item to rename it, delete it, or perform other tasks.
Right-click on the orb to edit the settings for the Start menu, to view this help file, or to
-stop the Start menu process.
+reload or stop the Start menu process.
@@ -149,7 +149,8 @@
Most settings will be changed immediately as you edit them. For example
you can edit the Start menu, then while the Settings dialog is open,
access the Start menu to see the changes. Small number of settings will
-require you to exit the Start menu before you can see the change.
+require you to reload the Start menu before you can see the change (right-click on the orb and
+select Reload).
@@ -330,7 +331,7 @@ Localization
Command Line
-StartMenu.exe supports 5 command line parameters: -open, -toggle, -togglenew, -exit and -settings.
+StartMenu.exe supports these command line parameters: -open, -toggle, -togglenew, -exit, -reload and -settings.
The first two do what the name suggests. One opens the classic Start menu, the other
toggles it. You can use the parameters to create a shortcut in your
@@ -343,6 +344,9 @@ Localization
Use "-exit" to exit the Start menu. This command will only work if the Start menu is not currently busy.
+Use "-reload" to exit the Start menu and start it again, so it goes through its startup anew. Like "-exit",
+it will only work if the Start menu is not currently busy. If the Start menu is not running, it just starts it.
+
Use "-settings" to open the Start menu settings. This is useful for creating a shortcut for editing the settings.
diff --git a/Src/StartMenu/StartMenu.cpp b/Src/StartMenu/StartMenu.cpp
index a1abea443..4a9152cc7 100644
--- a/Src/StartMenu/StartMenu.cpp
+++ b/Src/StartMenu/StartMenu.cpp
@@ -365,6 +365,35 @@ DWORD PerformOsUpgradeTask(bool silent)
return error;
}
+// For -reload: asks the running menu to exit and waits until its process has ended, not just released the mutex, so
+// that it is out of Explorer before this process hooks it. Then this process owns the mutex and carries on as the menu.
+// Returns false if the running menu wasn't found or didn't exit in time; it is left running then
+static bool TakeOverFromRunningMenu( HANDLE hMutex )
+{
+ const DWORD EXIT_TIMEOUT=20000; // ms; exiting is quick unless the menu is busy
+ const DWORD MUTEX_TIMEOUT=2000; // ms; the mutex is released just before the process ends
+
+ HWND hwnd=FindWindow(L"OpenShellMenu.CStartHookWindow",L"StartHookWindow");
+ DWORD pid=0;
+ HANDLE hProcess=(hwnd && GetWindowThreadProcessId(hwnd,&pid))?OpenProcess(SYNCHRONIZE,FALSE,pid):NULL;
+ if (!hProcess)
+ {
+ DllLogToFile(STARTUP_LOG,L"StartMenu: reload - the running menu was not found");
+ return false;
+ }
+
+ DllLogToFile(STARTUP_LOG,L"StartMenu: reload - asking the running menu to exit");
+ PostMessage(hwnd,WM_OPEN,MSG_EXIT,0);
+ DWORD wait=WaitForSingleObject(hProcess,EXIT_TIMEOUT);
+ CloseHandle(hProcess);
+ if (wait==WAIT_OBJECT_0)
+ wait=WaitForSingleObject(hMutex,MUTEX_TIMEOUT);
+ if (wait==WAIT_OBJECT_0 || wait==WAIT_ABANDONED)
+ return true;
+ DllLogToFile(STARTUP_LOG,L"StartMenu: reload - the running menu did not exit");
+ return false;
+}
+
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrCmdLine, int nCmdShow )
{
/* CoInitialize(NULL);
@@ -563,6 +592,8 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
else if (wcsstr(lpstrCmdLine,L"-settings")!=NULL) open=MSG_SETTINGS;
else if (wcsstr(lpstrCmdLine,L"-reloadsettings")!=NULL) open=MSG_RELOADSETTINGS;
else if (wcsstr(lpstrCmdLine,L"-exit")!=NULL) open=MSG_EXIT;
+ // -reload: make the running menu exit, then start as usual (the Reload command on the start button's context menu)
+ bool bReload=(open==CMD_NONE && wcsstr(lpstrCmdLine,L"-reload")!=NULL);
{
const wchar_t *pXml=wcsstr(lpstrCmdLine,L"-xml ");
@@ -648,6 +679,15 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
if (bHookExplorer)
{
hMutex=CreateMutex(NULL,TRUE,mutexName);
+ if ((GetLastError()==ERROR_ALREADY_EXISTS || GetLastError()==ERROR_ACCESS_DENIED) && bReload && hMutex)
+ {
+ if (!TakeOverFromRunningMenu(hMutex))
+ {
+ CloseHandle(hMutex);
+ return 0;
+ }
+ SetLastError(ERROR_SUCCESS);
+ }
if (GetLastError()==ERROR_ALREADY_EXISTS || GetLastError()==ERROR_ACCESS_DENIED)
{
if (open==MSG_TOGGLE || open==CMD_TOGGLE_NEW)
diff --git a/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp b/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
index d487ee099..9fdb5dffe 100644
--- a/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
+++ b/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
@@ -1654,6 +1654,17 @@ static void ComputeTaskbarColors( int *data )
data[3]=0;
}
+// Exits the menu and starts it again: StartMenu.exe -reload, from this DLL's folder, makes the running menu exit,
+// waits for it, and carries on as the menu
+static void ReloadStartMenu( void )
+{
+ wchar_t exe[_MAX_PATH];
+ GetModuleFileName(g_Instance,exe,_countof(exe));
+ PathRemoveFileSpec(exe);
+ PathAppend(exe,L"StartMenu.exe");
+ ShellExecute(NULL,NULL,exe,L"-reload",NULL,SW_SHOWNORMAL);
+}
+
static void ShowWinX( void )
{
if (IsWin11())
@@ -4122,6 +4133,7 @@ if (!g_bTrimHooks)
CMD_OPEN_ALL,
CMD_EXPLORER,
CMD_OPEN_PINNED,
+ CMD_RELOAD,
};
// right-click on the start button - open the context menu (Settings, Help, Exit)
@@ -4156,9 +4168,14 @@ if (!g_bTrimHooks)
AppendMenu(menu,MF_STRING,CMD_HELP,FindTranslation(L"Menu.MenuHelp",L"Help"));
if (GetSettingBool(L"EnableExit"))
{
+ // Reload exits and starts the menu again, so it goes with Exit
+ AppendMenu(menu,MF_STRING,CMD_RELOAD,FindTranslation(L"Menu.MenuReload",L"Reload"));
AppendMenu(menu,MF_STRING,CMD_EXIT,FindTranslation(L"Menu.MenuExit",L"Exit"));
if (!CMenuContainer::CanShowMenu())
+ {
+ EnableMenuItem(menu,CMD_RELOAD,MF_BYCOMMAND|MF_DISABLED);
EnableMenuItem(menu,CMD_EXIT,MF_BYCOMMAND|MF_DISABLED);
+ }
}
if (GetMenuItemCount(menu)>count0)
{
@@ -4182,6 +4199,11 @@ if (!g_bTrimHooks)
ShowHelp();
return TRUE;
}
+ if (res==CMD_RELOAD)
+ {
+ ReloadStartMenu();
+ return TRUE;
+ }
if (res==CMD_EXIT)
{
LRESULT res=CallNextHookEx(NULL,code,wParam,lParam);
diff --git a/Src/StartMenu/StartMenuL10N.ini b/Src/StartMenu/StartMenuL10N.ini
index 8c915b8e4..e8fe39381 100644
--- a/Src/StartMenu/StartMenuL10N.ini
+++ b/Src/StartMenu/StartMenuL10N.ini
@@ -1060,6 +1060,7 @@ Menu.ExploreAll = E&xplore All Users
Menu.MenuSettings = Settings
Menu.MenuHelp = Help
Menu.MenuExit = Exit
+Menu.MenuReload = Reload
Menu.LogoffTitle = Log Off Windows
Menu.LogoffPrompt = Are you sure you want to log off?
Menu.LogoffYes = &Log Off