diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index 07e96fcc2e5..55244118c9d 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -315,16 +315,29 @@ AppHost* WindowEmperor::_mostRecentWindow() const noexcept void WindowEmperor::HandleCommandlineArgs(int nCmdShow) { + // When running without package identity, set an explicit AppUserModelID so + // that toast notifications (and other shell features like taskbar grouping) + // work correctly. We include... + // - a hash of the executable path + // - a hash of the user SID + // This prevents crosstalk between different portable/unpackaged installations. + // The same isolation strategy is used for the single-instance mutex below. + std::wstring unpackagedAumid; + std::wstring windowClassName; windowClassName.reserve(64); // "Windows Terminal Preview Admin 0123456789012345 0123456789012345" #if defined(WT_BRANDING_RELEASE) windowClassName.append(L"Windows Terminal"); + unpackagedAumid = L"Microsoft.WindowsTerminal"; #elif defined(WT_BRANDING_PREVIEW) windowClassName.append(L"Windows Terminal Preview"); + unpackagedAumid = L"Microsoft.WindowsTerminalPreview"; #elif defined(WT_BRANDING_CANARY) windowClassName.append(L"Windows Terminal Canary"); + unpackagedAumid = L"Microsoft.WindowsTerminalCanary"; #else windowClassName.append(L"Windows Terminal Dev"); + unpackagedAumid = L"WindowsTerminalDev"; #endif if (Utils::IsRunningElevated()) { @@ -336,8 +349,10 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow) const auto hash = til::hash(path); #ifdef _WIN64 fmt::format_to(std::back_inserter(windowClassName), FMT_COMPILE(L" {:016x}"), hash); + fmt::format_to(std::back_inserter(unpackagedAumid), FMT_COMPILE(L".{:016x}"), hash); #else fmt::format_to(std::back_inserter(windowClassName), FMT_COMPILE(L" {:08x}"), hash); + fmt::format_to(std::back_inserter(unpackagedAumid), FMT_COMPILE(L".{:08x}"), hash); #endif } @@ -351,6 +366,15 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow) #else fmt::format_to(std::back_inserter(windowClassName), FMT_COMPILE(L" {:08x}"), hash); #endif + if (!IsPackaged()) + { +#ifdef _WIN64 + fmt::format_to(std::back_inserter(unpackagedAumid), FMT_COMPILE(L".{:016x}"), hash); +#else + fmt::format_to(std::back_inserter(unpackagedAumid), FMT_COMPILE(L".{:08x}"), hash); +#endif + LOG_IF_FAILED(SetCurrentProcessExplicitAppUserModelID(unpackagedAumid.c_str())); + } } // Windows Terminal is a single-instance application. Either acquire ownership