-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Profile auto-elevation, version 3 (#12137)
## Summary of the Pull Request This is the resurrection of #8514 and #11310. WE determined that we didn't want to do #11308 after all, so this should be profile auto-elevation, without the warning. This PR adds two features: * the `elevate: bool` property to profiles - If the user is running unelevated, **and** `elevate` is set to `true`, then instead of opening a new tab, we'll open an elevated Terminal window with the profile. - Otherwise, we'll just open a new tab in the existing window. This includes cases where the window is elevated, and the profile is set to `elevate:false`. `elevate:false` basically just means "do nothing special with me". * the `elevate: bool?` property to `NewTerminalArgs` (`newTab`, `splitPane`) - This allows a user to create an action that will elevate the profile, even if the profile is not otherwise set to auto-elevate. - `elevate:null` (_the default_) does not change the profile's elevation status. The action will use whatever is set by the profile. - `elevate:true` will attempt to auto-elevate the profile - `elevate:false` will do nothing special. ## References * #5000 for obvious reasons * Spec'd in #8455 ## PR Checklist * [x] Closes #632 * [x] I work here * [x] Tests added/passed * [ ] Requires documentation to be updated - sure does, but that'll come all at the end. ## Detailed Description of the Pull Request / Additional comments After playing with de-elevation a bit, it turns out it behaves weirdly with packaged applications. I can try and ask `explorer.exe` to launch the process on our behalf. However, if the thing we're launching is an execution alias (`wt.exe`), and we're elevated, then the child process will _still launch elevated_. There's also something super BODGEY at work here. `ShellExecute` is the function we use to ask the OS to elevate something for us. But `ShellExecute` needs to be able to send a window message to the process that called it (if the caller was a WINDOWS subsystem application). So if we die immediately after calling `ShellExecute`, then the elevated process never actually spawns - sad. So we're adding a helper process, `elevate-shim.exe`, that lives in our process. That'll be the one that actually calls `ShellExecute`, so that it can live for the duration of the UAC prompt. ## Validation Steps Performed * Ran tests * Opened a bunch of terminal tabs at various different elevation levels * opened new splits too * In the defaults (base layer) as well, for madness Some settings to use for testing <details> ```jsonc "keybindings" : [ ////////// ELEVATION /////////////// { "keys": "f1", "name": "ELEVATED TAB", "icon": "\uEA18", "command": { "action": "newTab", "elevate": true } }, { "keys": "f2", "name": "ELEVATED, Color", "icon": "\uEA18", "command": { "action": "newTab", "elevate": true, "commandline": "PowerShell.exe", "startingDirectory": "C:\\Windows", "tabColor": "#bbaa00" } }, { "keys": "f3", "name": "unelevated ELEVATED", "icon": "🙃", "command": { "action": "newTab", "elevate": false, "profile": "elevated cmd" } }, ////////////////////////////// ], "profiles": { "defaults": { "elevate": true, }, "list": [ { "hidden":false, "name" : "cmd", "commandline" : "cmd.exe", "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", "startingDirectory" : "%USERPROFILE%", "opacity" : 20 }, { "name" : "the COOLER cmd", "commandline" : "c:\\windows\\system32\\cmd.exe", "startingDirectory" : "%USERPROFILE%", }, { "name" : "the sneaky cmd", "commandline" : "c:\\windows\\system32\\cmd.exe /k echo sneaky sneaks", "startingDirectory" : "%USERPROFILE%", }, { "name": "elevated cmd", "commandline": "cmd.exe /k echo This profile is always elevated", "startingDirectory" : "well this is garbage", "elevate": true, "background": "#9C1C0C", "tabColor": "#9C1C0C", "colorScheme": "Desert" }, { "name": "unelevated cmd", "commandline": "cmd.exe /k echo This profile is just as elevated as you started with", "elevate": false, "background": "#1C0C9C", "tabColor": "#1C0C9C", "colorScheme": "DotGov", "useAcrylic": true }, ] ``` </details> Also try: * `wtd nt -p "elevated cmd" ; sp -p "elevated cmd"` * `wtd nt -p "elevated cmd" ; nt -p "elevated cmd"` This was merged manually via ``` git diff dev/migrie/f/non-terminal-content-elevation-warning dev/migrie/f/632-on-warning-dialog > ..\632.patch git apply ..\632.patch --ignore-whitespace --reject ```
- Loading branch information
1 parent
4455bdb
commit bc97af7
Showing
18 changed files
with
689 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
#include <string> | ||
#include <filesystem> | ||
|
||
#define WIN32_LEAN_AND_MEAN | ||
#include <windows.h> | ||
#include <wil/stl.h> | ||
#include <wil/resource.h> | ||
#include <wil/win32_helpers.h> | ||
#include <shellapi.h> | ||
|
||
// BODGY | ||
// | ||
// If we try to do this in the Terminal itself, then there's a bunch of weird | ||
// things that can go wrong and prevent the elevated Terminal window from | ||
// getting created. Specifically, if the origin Terminal exits right away after | ||
// spawning the elevated WT, then ShellExecute might not successfully complete | ||
// the elevation. What's even more, the Terminal will mysteriously crash | ||
// somewhere in XAML land. | ||
// | ||
// To mitigate this, the Terminal will call into us with the commandline it | ||
// wants elevated. We'll hang around until ShellExecute is finished, so that the | ||
// process can successfully elevate. | ||
|
||
#pragma warning(suppress : 26461) // we can't change the signature of wWinMain | ||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR pCmdLine, int) | ||
{ | ||
// All of the args passed to us (something like `new-tab -p {guid}`) are in | ||
// pCmdLine | ||
|
||
// Get the path to WindowsTerminal.exe, which should live next to us. | ||
std::filesystem::path module{ wil::GetModuleFileNameW<std::wstring>(nullptr) }; | ||
// Swap elevate-shim.exe for WindowsTerminal.exe | ||
module.replace_filename(L"WindowsTerminal.exe"); | ||
|
||
// Go! | ||
|
||
// disable warnings from SHELLEXECUTEINFOW struct. We can't fix that. | ||
#pragma warning(push) | ||
#pragma warning(disable : 26476) // Macro uses naked union over variant. | ||
SHELLEXECUTEINFOW seInfo{ 0 }; | ||
#pragma warning(pop) | ||
|
||
seInfo.cbSize = sizeof(seInfo); | ||
seInfo.fMask = SEE_MASK_DEFAULT; | ||
seInfo.lpVerb = L"runas"; // This asks the shell to elevate the process | ||
seInfo.lpFile = module.c_str(); // This is `...\WindowsTerminal.exe` | ||
seInfo.lpParameters = pCmdLine; // This is `new-tab -p {guid}` | ||
seInfo.nShow = SW_SHOWNORMAL; | ||
LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Microsoft Visual C++ generated resource script. | ||
// | ||
#include "resource.h" | ||
|
||
#define APSTUDIO_READONLY_SYMBOLS | ||
///////////////////////////////////////////////////////////////////////////// | ||
// | ||
// Generated from the TEXTINCLUDE 2 resource. | ||
// | ||
#include "winres.h" | ||
///////////////////////////////////////////////////////////////////////////// | ||
#undef APSTUDIO_READONLY_SYMBOLS | ||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
// English (United States) resources | ||
|
||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) | ||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US | ||
#pragma code_page(1252) | ||
|
||
#ifdef APSTUDIO_INVOKED | ||
///////////////////////////////////////////////////////////////////////////// | ||
// | ||
// TEXTINCLUDE | ||
// | ||
|
||
1 TEXTINCLUDE | ||
BEGIN | ||
"resource.h\0" | ||
END | ||
|
||
2 TEXTINCLUDE | ||
BEGIN | ||
"#include ""winres.h""\0" | ||
END | ||
|
||
3 TEXTINCLUDE | ||
BEGIN | ||
"\r\n" | ||
"\0" | ||
END | ||
|
||
#endif // APSTUDIO_INVOKED | ||
|
||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
// | ||
// Icon | ||
// | ||
|
||
// Icon with lowest ID value placed first to ensure application icon | ||
// remains consistent on all systems. | ||
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico" | ||
|
||
#endif // English (United States) resources | ||
///////////////////////////////////////////////////////////////////////////// | ||
|
||
|
||
|
||
#ifndef APSTUDIO_INVOKED | ||
///////////////////////////////////////////////////////////////////////////// | ||
// | ||
// Generated from the TEXTINCLUDE 3 resource. | ||
// | ||
|
||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
#endif // not APSTUDIO_INVOKED | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup Label="Globals"> | ||
<ProjectGuid>{416fd703-baa7-4f6e-9361-64f550ec8fca}</ProjectGuid> | ||
<Keyword>Win32Proj</Keyword> | ||
<RootNamespace>elevate-shim</RootNamespace> | ||
<ProjectName>elevate-shim</ProjectName> | ||
<TargetName>elevate-shim</TargetName> | ||
<ConfigurationType>Application</ConfigurationType> | ||
</PropertyGroup> | ||
|
||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" /> | ||
<Import Project="$(OpenConsoleDir)src\common.build.pre.props" /> | ||
|
||
<!-- Source Files --> | ||
<ItemGroup> | ||
<ClCompile Include="elevate-shim.cpp"> | ||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | ||
</ClCompile> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ResourceCompile Include="elevate-shim.rc" /> | ||
</ItemGroup> | ||
|
||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" /> | ||
|
||
<ItemDefinitionGroup> | ||
<Link> | ||
<!-- Remove all non-onecore dependencies --> | ||
<AdditionalDependencies>onecore.lib</AdditionalDependencies> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//{{NO_DEPENDENCIES}} | ||
// Microsoft Visual C++ generated include file. | ||
// Used by wt.rc | ||
// | ||
#define IDI_APPICON 101 | ||
|
||
// Next default values for new objects | ||
// | ||
#ifdef APSTUDIO_INVOKED | ||
#ifndef APSTUDIO_READONLY_SYMBOLS | ||
#define _APS_NEXT_RESOURCE_VALUE 102 | ||
#define _APS_NEXT_COMMAND_VALUE 40001 | ||
#define _APS_NEXT_CONTROL_VALUE 1001 | ||
#define _APS_NEXT_SYMED_VALUE 101 | ||
#endif | ||
#endif |
Oops, something went wrong.