Enable holding ctrl to open the Terminal elevated from File Explorer

## Summary of the Pull Request
This pull request adds support for holding the control key and clicking
the Open Terminal Here context menu item to elevate the request.
## References and Relevant Issues
#14810

## Detailed Description of the Pull Request / Additional comments

## Validation Steps Performed

## PR Checklist
- [x] Closes #14810
- [ ] Tests added/passed
- [ ] Documentation updated
- If checked, please file a pull request on [our docs
repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
- [ ] Schema updated (if necessary)

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
This commit is contained in:
James Pack
2023-04-04 12:24:33 -04:00
committed by GitHub
parent 47a17cf2d7
commit da995a014f
3 changed files with 26 additions and 2 deletions

View File

@@ -27,6 +27,8 @@ HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray,
IBindCtx* /*pBindContext*/)
try
{
const auto runElevated = IsControlPressed();
wil::com_ptr_nothrow<IShellItem> psi;
RETURN_IF_FAILED(GetBestLocationFromSelectionOrSite(psiItemArray, psi.put()));
if (!psi)
@@ -42,10 +44,18 @@ try
STARTUPINFOEX siEx{ 0 };
siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
std::filesystem::path modulePath{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
std::wstring cmdline;
RETURN_IF_FAILED(wil::str_printf_nothrow(cmdline, LR"-("%s" -d %s)-", GetWtExePath().c_str(), QuoteAndEscapeCommandlineArg(pszName.get()).c_str()));
if (runElevated)
{
RETURN_IF_FAILED(wil::str_printf_nothrow(cmdline, LR"-(-d %s)-", QuoteAndEscapeCommandlineArg(pszName.get()).c_str()));
}
else
{
RETURN_IF_FAILED(wil::str_printf_nothrow(cmdline, LR"-("%s" -d %s)-", GetWtExePath().c_str(), QuoteAndEscapeCommandlineArg(pszName.get()).c_str()));
}
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(
nullptr, // lpApplicationName
runElevated ? modulePath.replace_filename(ElevateShimExe).c_str() : nullptr, // if elevation requested pass the elevate-shim.exe as the application name
cmdline.data(),
nullptr, // lpProcessAttributes
nullptr, // lpThreadAttributes
@@ -193,3 +203,15 @@ HRESULT OpenTerminalHere::GetBestLocationFromSelectionOrSite(IShellItemArray* ps
RETURN_IF_FAILED(psi.copy_to(location));
return S_OK;
}
// This method checks if any of the ctrl keys are pressed during activation of the shell extension
bool OpenTerminalHere::IsControlPressed()
{
const auto ControlPressed = 1U;
const auto control = GetKeyState(VK_CONTROL);
const auto leftControl = GetKeyState(VK_LCONTROL);
const auto rightControl = GetKeyState(VK_RCONTROL);
return WI_IsFlagSet(control, ControlPressed) || WI_IsFlagSet(leftControl, ControlPressed) || WI_IsFlagSet(rightControl, ControlPressed);
}

View File

@@ -58,6 +58,7 @@ struct
private:
HRESULT GetLocationFromSite(IShellItem** location) const noexcept;
HRESULT GetBestLocationFromSelectionOrSite(IShellItemArray* psiArray, IShellItem** location) const noexcept;
bool IsControlPressed();
wil::com_ptr_nothrow<IUnknown> site_;
};

View File

@@ -2,6 +2,7 @@ constexpr std::wstring_view WtExe{ L"wt.exe" };
constexpr std::wstring_view WtdExe{ L"wtd.exe" };
constexpr std::wstring_view WindowsTerminalExe{ L"WindowsTerminal.exe" };
constexpr std::wstring_view LocalAppDataAppsPath{ L"%LOCALAPPDATA%\\Microsoft\\WindowsApps\\" };
constexpr std::wstring_view ElevateShimExe{ L"elevate-shim.exe" };
_TIL_INLINEPREFIX bool IsPackaged()
{