Repository: microsoft/terminal (language: cpp)

Issue:
Starting an elevated profile from the jumplist will relaunch persisted unelevated windows
1. Persist an unelevated Terminal layout
2. Add an elevated profile
3. close all terminal windows, so we launch "from cold"
4. Use the jumplist to launch the elevated profile

#### expected:

just the elevated window appears

#### actual:

the elevated window appears, and the unelevated persisted layout comes back too


there's a theoretical fix in 46c6403 / 5614fde, but that was for a crash. I suspect it would also fix this.

Regressed in #12137 

Crash opening an elevated profile from the taskbar jumplist
### Windows Terminal version

main 7061c54

### Windows build number

10.0.22000.434

### Other Software

_No response_

### Steps to reproduce

1. Create an elevated profile.
   ```json
            {
                "colorScheme": "Campbell Powershell",
                "commandline": "\"C:\\Program Files\\PowerShell\\7\\pwsh.exe\"",
                "guid": "{14b805d7-b545-418a-b1e8-1fdccd6197f7}",
                "hidden": false,
                "icon": "ms-appx:///ProfileIcons/pwsh.png",
                "name": "PowerShell (Elevated)",
                "startingDirectory": "%USERPROFILE%",
                "elevate": true
            }
   ```
2. Right click on the terminal icon in the taskbar and select your elevated profile.

### Expected Behavior

Nothing to crash.

### Actual Behavior

The un-elevated copy of terminal, which spawned the elevated one crashes. The elevated copy of terminal starts up successfully and can be used as expected. The call-stack seems to be deep within XAML with the last frame in terminal at the `AppHost` destructor, so my _guess_ would be that the app is closing before the XAML stack is fully initialised, leading to the crash.

```
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


KEY_VALUES_STRING: 1

    Key  : AV.Dereference
    Value: NullClassPtr

    Key  : AV.Fault
    Value: Read

    Key  : Analysis.CPU.mSec
    Value: 5592

    Key  : Analysis.DebugAnalysisManager
    Value: Create

    Key  : Analysis.Elapsed.mSec
    Value: 53234

    Key  : Analysis.Init.CPU.mSec
    Value: 1000

    Key  : Analysis.Init.Elapsed.mSec
    Value: 6342

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 651

    Key  : Timeline.Process.Start.DeltaSec
    Value: 2

    Key  : WER.OS.Branch
    Value: co_release

    Key  : WER.OS.Timestamp
    Value: 2021-06-04T16:28:00Z

    Key  : WER.OS.Version
    Value: 10.0.22000.1


FILE_IN_CAB:  WindowsTerminal.exe.22092.dmp

NTGLOBALFLAG:  0

PROCESS_BAM_CURRENT_THROTTLED: 0

PROCESS_BAM_PREVIOUS_THROTTLED: 0

APPLICATION_VERIFIER_FLAGS:  0

CONTEXT:  (.ecxr)
rax=0000000000000000 rbx=0000005a1d4fe570 rcx=0000000000000000
rdx=0000070000000700 rsi=0000000000000000 rdi=0000005a1d4fe080
rip=00007ff865c9ae8f rsp=0000005a1d4fe820 rbp=0000005a1d4fe929
 r8=00000175cd6a7ae0  r9=0000005a1d4fea70 r10=00000fff0cbdbde1
r11=aa888aaaa8aaaaaa r12=00000175c2634ec0 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010244
Windows_UI_Xaml!WindowsGraphicsDeviceManager::WaitForInitializationThreadCompletion+0x1f:
00007ff8`65c9ae8f 48397910        cmp     qword ptr [rcx+10h],rdi ds:00000000`00000010=????????????????
Resetting default scope

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 00007ff865c9ae8f (Windows_UI_Xaml!WindowsGraphicsDeviceManager::WaitForInitializationThreadCompletion+0x000000000000001f)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000001
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: 0000000000000010
Attempt to read from address 0000000000000010

PROCESS_NAME:  WindowsTerminal.exe

READ_ADDRESS:  0000000000000010 

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  0000000000000000

EXCEPTION_PARAMETER2:  0000000000000010

STACK_TEXT:  
0000005a`1d4fe820 00007ff8`65c9a75e     : 00000000`00000000 00000700`00000700 00000000`00000000 00000175`cd7deed0 : Windows_UI_Xaml!WindowsGraphicsDeviceManager::WaitForInitializationThreadCompletion+0x1f
0000005a`1d4fe880 00007ff8`65e6503c     : 4327ffff`fffff200 00000000`00000001 00000700`00000700 00000175`cd7deee0 : Windows_UI_Xaml!CCoreServices::GetMaxTextureSize+0x3e
0000005a`1d4fe8b0 00007ff8`65e64cb3     : 00000175`c2678130 00000700`00000700 00000175`cd763dd0 00007ff8`83dfcb61 : Windows_UI_Xaml!CLoadedImageSurface::IsVirtualPossible+0x30
0000005a`1d4fe8e0 00007ff8`65e64c08     : 00000700`00000700 00000175`c6e1f428 00000175`cd6a7ae0 00000175`c43ac760 : Windows_UI_Xaml!CLoadedImageSurface::StartDecodingHelper+0x77
0000005a`1d4fe990 00007ff8`65e64bb2     : 0000005a`00000000 00000175`cd6a7b58 00000000`00000010 0000005a`1d4feaa8 : Windows_UI_Xaml!CLoadedImageSurface::StartFinalSizeDecoding+0x3c
0000005a`1d4fe9c0 00007ff8`65c849b8     : 00000000`00000000 00007ff8`65d340ed 00000000`00000000 00000000`00000030 : Windows_UI_Xaml!CLoadedImageSurface::OnImageViewUpdated+0x42
0000005a`1d4fe9f0 00007ff8`65c84939     : 00000000`00000000 00000175`cd763df0 00000000`00000000 00000000`00000000 : Windows_UI_Xaml!ImageViewBase::TriggerViewUpdated+0x4c
0000005a`1d4fea20 00007ff8`65c84a3a     : 00000175`cd6fae60 00000175`c68939a0 00000175`cd6faee0 00000000`00000000 : Windows_UI_Xaml!ImageMetadataViewImpl::SetEncodedImageData+0x51
0000005a`1d4fea50 00007ff8`65b8f05c     : 00000175`c6893790 00000000`00000000 00000175`c6893790 00000000`00000000 : Windows_UI_Xaml!ImageCache::SetEncodedImageData+0x76
0000005a`1d4fea90 00007ff8`65b8efae     : 00000175`c6893790 00000000`00000000 00000175`c68914b0 0000005a`1d4feb90 : Windows_UI_Xaml!ImageCache::GotDownloadResponse+0x84
0000005a`1d4feae0 00007ff8`65b96d4d     : 00000175`cd6fae60 00000175`c68914b0 0000005a`1d4febb8 0000005a`1d4feb98 : Windows_UI_Xaml!ImageCacheDownloadResponseTask::Execute+0x2e
0000005a`1d4feb10 00007ff8`65b8a299     : 00000000`00000000 00000000`00000000 0000005a`1d4febd0 00000175`c269f710 : Windows_UI_Xaml!ImageCacheDownloadCallbackMarshaller::GotResponse+0x9d
0000005a`1d4feb50 00007ff8`65bae638     : 00000175`00040007 00007ff8`00000001 00000175`cd6faeb0 00000000`00000000 : Windows_UI_Xaml!CDownloader::CreateUnsecureDownloadRequest+0x1f9
0000005a`1d4fec10 00007ff8`65b6b671     : 00000175`cd6c6220 0000005a`1d4fecb0 00000175`cd6c61d0 00000175`cd73bf00 : Windows_UI_Xaml!CommonBrowserHost::UnsecureDownload+0x58
0000005a`1d4fec50 00007ff8`65b6b51a     : 00000175`cd6faeb0 00000175`cd6fae60 00000175`c2678130 00000175`cd6d6d80 : Windows_UI_Xaml!CCoreServices::UnsecureDownloadFromSite+0x131
0000005a`1d4fece0 00007ff8`65dd62d5     : 00000175`cd6fae60 00000000`00000000 00000175`cd73c260 00000000`00000000 : Windows_UI_Xaml!ImageCache::Download+0xc2
0000005a`1d4fed50 00007ff8`65e416c0     : 00000000`00000000 00000175`cd739590 00000175`cd73c260 00000175`cd6d6d80 : Windows_UI_Xaml!ImageCache::ProcessDecodeRequests+0xb5
0000005a`1d4fed80 00007ff8`65ccfaa1     : 00000000`00000000 00000175`c26784a0 00000175`c2678130 00000000`00000000 : Windows_UI_Xaml!ImageTaskDispatcher::Execute+0xe0
0000005a`1d4fedb0 00007ff8`65dc9a70     : 00000000`00000000 0000005a`1d4feeb0 00000000`00000000 00007ff8`65cee3f7 : Windows_UI_Xaml!CCoreServices::ResetCoreWindowVisualTree+0x23d
0000005a`1d4fee00 00007ff8`65cedc46     : 00000000`00000000 00000000`00000000 00000175`c2624080 00000175`c2624070 : Windows_UI_Xaml!CommonBrowserHost::ResetVisualTree+0x50
0000005a`1d4fee30 00007ff8`65ced7b1     : 00000000`00000000 00007ff8`65e7e900 0000005a`1d4feeb0 00000000`00000000 : Windows_UI_Xaml!CJupiterControl::ResetVisualTree+0x4e
0000005a`1d4fee60 00007ff8`65ced152     : 00000000`00000000 0000005a`1d4feed0 00000000`00000000 00000000`00000000 : Windows_UI_Xaml!DirectUI::DXamlCore::CommonShutdown+0xb9
0000005a`1d4feed0 00007ff8`65cf1c0f     : 00000175`c26761d0 00000000`00000000 00000175`c26761d0 0000005a`1d4ff0b8 : Windows_UI_Xaml!DirectUI::DXamlCore::DeinitializeInstance+0x172
0000005a`1d4fef00 00007ff8`667adb4f     : 00000000`00000000 00000175`c26761d0 0000005a`1d4ff0b8 00000175`c26761d0 : Windows_UI_Xaml!DirectUI::DXamlCore::Deinitialize+0x8f
0000005a`1d4fef30 00007ff8`65f203b3     : 00000175`cd711710 00000175`c26761d0 00007ff8`87b88330 00007ff8`8af5d8ab : Windows_UI_Xaml!DirectUI::WindowsXamlManager::XamlCore::Close+0x11b
0000005a`1d4fef70 00007ff8`87b88350     : 00000175`cd711710 00007ff8`8d285000 00000175`00000000 00007ff8`8d4872b4 : Windows_UI_Xaml!Microsoft::WRL::Details::DelegateArgTraits<long (__cdecl Windows::System::IDispatcherQueueHandler::*)(void)>::DelegateInvokeHelper<Microsoft::WRL::Implements<Microsoft::WRL::RuntimeClassFlags<2>,Windows::System::IDispatcherQueueHandler,Microsoft::WRL::FtmBase>,<lambda_e4f49de40a4de9a39b79809f2fbaa002> &,-1>::Invoke+0x13
0000005a`1d4fefa0 00007ff8`87b51984     : 0000005a`1d4ff078 0000005a`1d4ff0b1 0000005a`1d4ff018 00000002`00000030 : CoreMessaging!Windows::System::DispatcherQueue::DeferInvokeCallback+0x20
0000005a`1d4fefd0 00007ff8`87b518de     : 00000175`c264dbd0 00007ff8`87b88330 00000175`c264dbd0 00007ff8`87b88330 : CoreMessaging!CFlat::SehSafe::Execute<<lambda_a81ff790741c2a62f2197c2561f5fe49> >+0x2c
0000005a`1d4ff000 00007ff8`87b4b41f     : 00000175`c6fc30b0 00007ff8`81aeaf08 00000000`00000000 00000175`c6fc1670 : CoreMessaging!Microsoft::CoreUI::ActionCallback::ImportAdapter$+0xae
0000005a`1d4ff040 00007ff8`87b4a93b     : 00000175`cd7ea780 00007ff8`8190291d 00000000`00000000 00000000`00000020 : CoreMessaging!Microsoft::CoreUI::Dispatch::DeferredCall::Callback_Dispatch+0x2bf
0000005a`1d4ff100 00007ff8`87b4a5bd     : 00000175`00000007 00000000`00000007 00000000`00000001 00000175`c26626d0 : CoreMessaging!Microsoft::CoreUI::Dispatch::DeferredCallDispatcher::Callback_OnDispatch+0x12b
0000005a`1d4ff1c0 00007ff8`87b4bc84     : 00000175`c263ba90 00000175`c264f640 00000175`c26652d0 0000005a`1d4ff718 : CoreMessaging!Microsoft::CoreUI::Dispatch::EventLoop::Callback_RunCoreLoop+0x2ed
0000005a`1d4ff280 00007ff8`87b4b7ec     : 00000175`c26652d0 00000175`c26652d0 00000175`c264dbd0 00000175`c264f640 : CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatch+0x214
0000005a`1d4ff310 00007ff8`87b47a0f     : 00000000`00000004 00007ff8`8c146578 00000000`00000000 00000175`c2650c80 : CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DoWork+0x1fc
0000005a`1d4ff3a0 00007ff8`8d201c4c     : 00000000`00000000 00000175`c2580000 00000000`00000001 00000000`00000001 : CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::WindowProc+0x4f
0000005a`1d4ff410 00007ff8`8d20179c     : 00000000`00000000 00007ff8`87b479c0 00000000`002f05d8 00000175`00000060 : user32!UserCallWinProcCheckWow+0x33c
0000005a`1d4ff580 00007ff8`8d214b4d     : 00000175`c2cd7400 0000005a`1d4ff7f0 00000000`00000005 00000000`00000000 : user32!DispatchClientMessage+0x9c
0000005a`1d4ff5e0 00007ff8`8d4872b4     : 00000000`00000001 00007ff8`81902dec 00000175`cd7ea280 00000000`00000000 : user32!_fnDWORD+0x3d
0000005a`1d4ff640 00007ff8`8aed13b4     : 00007ff8`8d209f0f 00000175`cd7ea280 00000000`00000000 00000000`00000000 : ntdll!KiUserCallbackDispatcherContinue
0000005a`1d4ff6c8 00007ff8`8d209f0f     : 00000175`cd7ea280 00000000`00000000 00000000`00000000 00007ff8`818b592f : win32u!NtUserPeekMessage+0x14
0000005a`1d4ff6d0 00007ff8`8d209e7a     : 00000000`00000001 00000175`c2cd7400 00000000`00000000 00000000`00000000 : user32!_PeekMessage+0x3f
0000005a`1d4ff740 00007ff8`828914f5     : 00000175`c2628a28 0000005a`1d4ff9b0 00000175`c2630340 00007ff8`8d40756d : user32!PeekMessageW+0x13a
0000005a`1d4ff7b0 00007ff8`828939b9     : 00000000`002f05d8 0000005a`1d4ff9e0 00000000`00000000 00000000`00000000 : Microsoft_Toolkit_Win32_UI_XamlHost+0x14f5
0000005a`1d4ff840 00007ff6`f4c893be     : 0000005a`1d4ff9e0 00000000`00000000 00000000`00000000 00000000`00000000 : Microsoft_Toolkit_Win32_UI_XamlHost+0x39b9
0000005a`1d4ff870 00007ff6`f4c8630f     : 00000000`00000000 00000000`00000001 00000000`00000000 00000000`00000000 : WindowsTerminal!AppHost::~AppHost+0x8e
0000005a`1d4ff8b0 00007ff6`f4cb4202     : 00000000`00000001 00000000`00000000 00000000`00000000 00000000`00000000 : WindowsTerminal!wWinMain+0x4af
0000005a`1d4ffb20 00007ff8`8c1b54e0     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : WindowsTerminal!__scrt_common_main_seh+0x106
0000005a`1d4ffb60 00007ff8`8d3e485b     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x10
0000005a`1d4ffb90 00000000`00000000     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2b


FAULTING_SOURCE_LINE:  onecoreuap\windows\dxaml\xcp\components\graphics\windowsgraphicsdevicemanager.cpp

FAULTING_SOURCE_FILE:  onecoreuap\windows\dxaml\xcp\components\graphics\windowsgraphicsdevicemanager.cpp

FAULTING_SOURCE_LINE_NUMBER:  17

FAULTING_SOURCE_CODE:  
No source found for 'onecoreuap\windows\dxaml\xcp\components\graphics\windowsgraphicsdevicemanager.cpp'


SYMBOL_NAME:  Windows_UI_Xaml!WindowsGraphicsDeviceManager::WaitForInitializationThreadCompletion+1f

MODULE_NAME: Windows_UI_Xaml

IMAGE_NAME:  Windows.UI.Xaml.dll

STACK_COMMAND:  ~0s ; .ecxr ; kb

FAILURE_BUCKET_ID:  NULL_CLASS_PTR_READ_c0000005_Windows.UI.Xaml.dll!WindowsGraphicsDeviceManager::WaitForInitializationThreadCompletion

OS_VERSION:  10.0.22000.1

BUILDLAB_STR:  co_release

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

IMAGE_VERSION:  10.0.22000.348

FAILURE_ID_HASH:  {e25e17fd-3d34-febf-009a-64ef61c97fd8}

Followup:     MachineOwner
---------
```


Discussion / hints:

That is REALLY weird. Does it pop an error message up at you, or just silently crash? I think I saw something similar in #12142, but the stack was very different. 
It just silently crashes. It happens every time too, so at least it's consistent.

Fix patch:
diff --git a/.github/actions/spelling/allow/allow.txt b/.github/actions/spelling/allow/allow.txt
index 442651d7c77..a4cc6161066 100644
--- a/.github/actions/spelling/allow/allow.txt
+++ b/.github/actions/spelling/allow/allow.txt
@@ -42,6 +42,7 @@ libfuzzer
 liga
 lje
 Llast
+llvm
 Lmid
 locl
 lorem
diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp
index 4cafee145a0..5fc8b1eed00 100644
--- a/src/cascadia/Remoting/WindowManager.cpp
+++ b/src/cascadia/Remoting/WindowManager.cpp
@@ -252,8 +252,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
 
         if (_peasant)
         {
-            // Inform the monarch of the time we were last activated
-            _monarch.HandleActivatePeasant(_peasant.GetLastActivatedArgs());
+            if (const auto& lastActivated{ _peasant.GetLastActivatedArgs() })
+            {
+                // Inform the monarch of the time we were last activated
+                _monarch.HandleActivatePeasant(lastActivated);
+            }
         }
 
         if (!_isKing)
diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp
index ec6ebf50fc5..4f774dc205a 100644
--- a/src/cascadia/TerminalApp/AppLogic.cpp
+++ b/src/cascadia/TerminalApp/AppLogic.cpp
@@ -1472,6 +1472,24 @@ namespace winrt::TerminalApp::implementation
         return _root != nullptr ? _root->ShouldUsePersistedLayout(_settings) : false;
     }
 
+    bool AppLogic::ShouldImmediatelyHandoffToElevated()
+    {
+        if (!_loadedInitialSettings)
+        {
+            // Load settings if we haven't already
+            LoadSettings();
+        }
+
+        return _root != nullptr ? _root->ShouldImmediatelyHandoffToElevated(_settings) : false;
+    }
+    void AppLogic::HandoffToElevated()
+    {
+        if (_root)
+        {
+            _root->HandoffToElevated(_settings);
+        }
+    }
+
     void AppLogic::SaveWindowLayoutJsons(const Windows::Foundation::Collections::IVector<hstring>& layouts)
     {
         std::vector<WindowLayout> converted;
diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h
index 19e891843b9..1d43f113ba5 100644
--- a/src/cascadia/TerminalApp/AppLogic.h
+++ b/src/cascadia/TerminalApp/AppLogic.h
@@ -81,6 +81,8 @@ namespace winrt::TerminalApp::implementation
         bool AlwaysOnTop() const;
 
         bool ShouldUsePersistedLayout();
+        bool ShouldImmediatelyHandoffToElevated();
+        void HandoffToElevated();
         hstring GetWindowLayoutJson(Microsoft::Terminal::Settings::Model::LaunchPosition position);
         void SaveWindowLayoutJsons(const Windows::Foundation::Collections::IVector<hstring>& layouts);
         void IdentifyWindow();
diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl
index 9121c3ccf9e..57e7a914e25 100644
--- a/src/cascadia/TerminalApp/AppLogic.idl
+++ b/src/cascadia/TerminalApp/AppLogic.idl
@@ -93,6 +93,8 @@ namespace TerminalApp
         TaskbarState TaskbarState{ get; };
 
         Boolean ShouldUsePersistedLayout();
+        Boolean ShouldImmediatelyHandoffToElevated();
+        void HandoffToElevated();
         String GetWindowLayoutJson(Microsoft.Terminal.Settings.Model.LaunchPosition position);
         void SaveWindowLayoutJsons(Windows.Foundation.Collections.IVector<String> layouts);
 
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index 4d0e4584054..1ef1087e2ae 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -302,6 +302,114 @@ namespace winrt::TerminalApp::implementation
                settings.GlobalSettings().FirstWindowPreference() == FirstWindowPreference::PersistedWindowLayout;
     }
 
+    // Method Description:
+    // - This is a bit of trickiness: If we're running unelevated, and the user
+    //   passed in only --elevate actions, the we don't _actually_ want to
+    //   restore the layouts here. We're not _actually_ about to create the
+    //   window. We're simply going to toss the commandlines
+    // Arguments:
+    // - <none>
+    // Return Value:
+    // - true if we're not elevated but all relevant pane-spawning actions are elevated
+    bool TerminalPage::ShouldImmediatelyHandoffToElevated(const CascadiaSettings& settings) const
+    {
+        if (!_startupActions || IsElevated())
+        {
+            // there arent startup actions, or we're elevated. In that case, go for it.
+            return false;
+        }
+
+        // Check that there's at least one action that's not just an elevated newTab action.
+        for (const auto& action : _startupActions)
+        {
+            NewTerminalArgs newTerminalArgs{ nullptr };
+
+            if (action.Action() == ShortcutAction::NewTab)
+            {
+                const auto& args{ action.Args().try_as<NewTabArgs>() };
+                if (args)
+                {
+                    newTerminalArgs = args.TerminalArgs();
+                }
+                else
+                {
+                    // This was a nt action that didn't have any args. The default
+                    // profile may want to be elevated, so don't just early return.
+                }
+            }
+            else if (action.Action() == ShortcutAction::SplitPane)
+            {
+                const auto& args{ action.Args().try_as<SplitPaneArgs>() };
+                if (args)
+                {
+                    newTerminalArgs = args.TerminalArgs();
+                }
+                else
+                {
+                    // This was a nt action that didn't have any args. The default
+                    // profile may want to be elevated, so don't just early return.
+                }
+            }
+            else
+            {
+                // This was not a new tab or split pane action.
+                // This doesn't affect the outcome
+                continue;
+            }
+
+            // It's possible that newTerminalArgs is null here.
+            // GetProfileForArgs should be resilient to that.
+            const auto profile{ settings.GetProfileForArgs(newTerminalArgs) };
+            if (profile.Elevate())
+            {
+                continue;
+            }
+
+            // The profile didn't want to be elevated, and we aren't elevated.
+            // We're going to open at least one tab, so return false.
+            return false;
+        }
+        return true;
+    }
+
+    // Method Description:
+    // - Escape hatch for immediately dispatching requests to elevated windows
+    //   when first launched. At this point in startup, the window doesn't exist
+    //   yet, XAML hasn't been started, but we need to dispatch these actions.
+    //   We can't just go through ProcessStartupActions, because that processes
+    //   the actions async using the XAML dispatcher (which doesn't exist yet)
+    // - DON'T CALL THIS if you haven't already checked
+    //   ShouldImmediatelyHandoffToElevated. If you're thinking about calling
+    //   this outside of the one place it's used, that's probably the wrong
+    //   solution.
+    // Arguments:
+    // - settings: the settings we should use for dispatching these actions. At
+    //   this point in startup, we hadn't otherwise been initialized with these,
+    //   so use them now.
+    // Return Value:
+    // - <none>
+    void TerminalPage::HandoffToElevated(const CascadiaSettings& settings)
+    {
+        if (!_startupActions)
+        {
+            return;
+        }
+
+        // Hookup our event handlers to the ShortcutActionDispatch
+        _settings = settings;
+        _HookupKeyBindings(_settings.ActionMap());
+        _RegisterActionCallbacks();
+
+        for (const auto& action : _startupActions)
+        {
+            // only process new tabs and split panes. They're all going to the elevated window anyways.
+            if (action.Action() == ShortcutAction::NewTab || action.Action() == ShortcutAction::SplitPane)
+            {
+                _actionDispatch->DoAction(action);
+            }
+        }
+    }
+
     // Method Description;
     // - Checks if the current window is configured to load a particular layout
     // Arguments:
@@ -1638,7 +1746,30 @@ namespace winrt::TerminalApp::implementation
                                   std::shared_ptr<Pane> newPane)
     {
         const auto focusedTab{ _GetFocusedTabImpl() };
-        _SplitPane(*focusedTab, splitDirection, splitSize, newPane);
+
+        // Clever hack for a crash in startup, with multiple sub-commands. Say
+        // you have the following commandline:
+        //
+        //   wtd nt -p "elevated cmd" ; sp -p "elevated cmd" ; sp -p "Command Prompt"
+        //
+        // Where "elevated cmd" is an elevated profile.
+        //
+        // In that scenario, we won't dump off the commandline immediately to an
+        // elevated window, because it's got the final unelevated split in it.
+        // However, when we get to that command, there won't be a tab yet. So
+        // we'd crash right about here.
+        //
+        // Instead, let's just promote this first split to be a tab instead.
+        // Crash avoided, and we don't need to worry about inserting a new-tab
+        // command in at the start.
+        if (!focusedTab && _tabs.Size() == 0)
+        {
+            _CreateNewTabFromPane(newPane);
+        }
+        else
+        {
+            _SplitPane(*focusedTab, splitDirection, splitSize, newPane);
+        }
     }
 
     // Method Description:
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index 91c76fd1040..b0d7e720fbb 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -64,6 +64,8 @@ namespace winrt::TerminalApp::implementation
         void Create();
 
         bool ShouldUsePersistedLayout(Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
+        bool ShouldImmediatelyHandoffToElevated(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
+        void HandoffToElevated(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
         std::optional<uint32_t> LoadPersistedLayoutIdx(Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
         winrt::Microsoft::Terminal::Settings::Model::WindowLayout LoadPersistedLayout(Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
         Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp
index 9a345e18b57..747169f5151 100644
--- a/src/cascadia/WindowsTerminal/AppHost.cpp
+++ b/src/cascadia/WindowsTerminal/AppHost.cpp
@@ -214,6 +214,20 @@ void AppHost::_HandleCommandlineArgs()
             }
         }
 
+        // This is a fix for GH#12190 and hopefully GH#12169.
+        //
+        // If the commandline we were provided is going to result in us only
+        // opening elevated terminal instances, then we need to not even create
+        // the window at all here. In that case, we're going through this
+        // special escape hatch to dispatch all the calls to elevate-shim, and
+        // then we're going to exit immediately.
+        if (_logic.ShouldImmediatelyHandoffToElevated())
+        {
+            _shouldCreateWindow = false;
+            _logic.HandoffToElevated();
+            return;
+        }
+
         // After handling the initial args, hookup the callback for handling
         // future commandline invocations. When our peasant is told to execute a
         // commandline (in the future), it'll trigger this callback, that we'll
@@ -231,7 +245,9 @@ void AppHost::_HandleCommandlineArgs()
         {
             const auto numPeasants = _windowManager.GetNumberOfPeasants();
             const auto layouts = ApplicationState::SharedInstance().PersistedWindowLayouts();
-            if (_logic.ShouldUsePersistedLayout() && layouts && layouts.Size() > 0)
+            if (_logic.ShouldUsePersistedLayout() &&
+                layouts &&
+                layouts.Size() > 0)
             {
                 uint32_t startIdx = 0;
                 // We want to create a window for every saved layout.


Test patch: