terminal/src/cascadia/wt/shim.cpp
Dustin L. Howett 592c634577
Build and ship an actual binary named wt that just launches WT (#6860)
Due to a shell limitation, Ctrl+Shift+Enter will not launch Windows
Terminal as Administrator. This is caused by the app execution alias and
the actual targeted executable not having the same name.

In addition, PowerShell has an issue detecting app execution aliases as
GUI/TUI applications. When you run wt from PowerShell, the shell will
wait for WT to exit before returning to the prompt. Having a shim that
immediately re-executes WindowsTerminal and then returns handily knocks
this issue out (as the process that PS was waiting for exits
immediately.)

This could cause a regression for anybody who tries to capture the PID
of wt.exe. Our process tree is not an API, and we have offered no
consistency guarantee on it.

VALIDATION
----------

Tested manual launch in a number of different scenarios:

* [x] start menu "wtd"
* [x] start menu tile
* [x] powertoys run
* [x] powertoys run ctrl+shift (admin)
* [x] powershell inbox, "core"
* [x] cmd
* [x] run dialog
* [x] run dialog ctrl+shift (admin)
* [x] run from a lnk with window mode=maximized

Fixes #4645 (PowerShell waits for wt)
Fixes #6625 (Can't launch as admin using C-S-enter)
2020-07-10 22:41:37 +00:00

37 lines
1.1 KiB
C++

#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>
#pragma warning(suppress : 26461) // we can't change the signature of wWinMain
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR pCmdLine, int)
{
std::filesystem::path module{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
// Cache our name (wt, wtd)
std::wstring ourFilename{ module.filename() };
// Swap wt[d].exe for WindowsTerminal.exe
module.replace_filename(L"WindowsTerminal.exe");
// Append the rest of the commandline to the saved name
std::wstring cmdline;
if (FAILED(wil::str_printf_nothrow(cmdline, L"%s %s", ourFilename.c_str(), pCmdLine)))
{
return 1;
}
// Get our startup info so it can be forwarded
STARTUPINFOW si{};
si.cb = sizeof(si);
GetStartupInfoW(&si);
// Go!
wil::unique_process_information pi;
return !CreateProcessW(module.c_str(), cmdline.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);
}