Add -ForceNoHandoff for compatibility; stop handoff for double-click launches (#9802)

Add flag that will ensure we do not handoff to a registered default console. Also for a bonus, allow double-click launches or explicit command line launches of conhost.exe with a binary argument to open with the inbox one.

## PR Checklist
* [x] Closes #9791 
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
* [x] Automated tests for parsing
* [x] Enable defapp, double click conhost.exe, opens as itself
* [x] Enable defapp, run conhost.exe runbox, opens as itself
* [x] Enable defapp, run conhost.exe powershell.exe runbox, opens as itself
* [x] Runbox cmd.exe/pwsh.exe trigger defapp handoff to Terminal
* [x] Shortcut to cmd.exe/pwsh.exe trigger defapp handoff to Terminal
* [x] Use CHOP tool to launch conhost with a server handle triggers handoff to Terminal
* [x] Use CHOP tool to launch conhost with a server handle and -ForceNoHandoff opens as itself
This commit is contained in:
Michael Niksa
2021-04-15 09:54:04 -07:00
committed by GitHub
parent eddb99e9b2
commit dba66da18d
4 changed files with 130 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ const std::wstring_view ConsoleArguments::SIGNAL_HANDLE_ARG = L"--signal";
const std::wstring_view ConsoleArguments::HANDLE_PREFIX = L"0x";
const std::wstring_view ConsoleArguments::CLIENT_COMMANDLINE_ARG = L"--";
const std::wstring_view ConsoleArguments::FORCE_V1_ARG = L"-ForceV1";
const std::wstring_view ConsoleArguments::FORCE_NO_HANDOFF_ARG = L"-ForceNoHandoff";
const std::wstring_view ConsoleArguments::FILEPATH_LEADER_PREFIX = L"\\??\\";
const std::wstring_view ConsoleArguments::WIDTH_ARG = L"--width";
const std::wstring_view ConsoleArguments::HEIGHT_ARG = L"--height";
@@ -115,6 +116,7 @@ ConsoleArguments::ConsoleArguments(const std::wstring& commandline,
_serverHandle = 0;
_signalHandle = 0;
_forceV1 = false;
_forceNoHandoff = false;
_width = 0;
_height = 0;
_inheritCursor = false;
@@ -144,6 +146,7 @@ ConsoleArguments& ConsoleArguments::operator=(const ConsoleArguments& other)
_inheritCursor = other._inheritCursor;
_receivedEarlySizeChange = other._receivedEarlySizeChange;
_runAsComServer = other._runAsComServer;
_forceNoHandoff = other._forceNoHandoff;
}
return *this;
@@ -449,6 +452,13 @@ void ConsoleArguments::s_ConsumeArg(_Inout_ std::vector<std::wstring>& args, _In
s_ConsumeArg(args, i);
hr = S_OK;
}
else if (arg == FORCE_NO_HANDOFF_ARG)
{
// Prevent default application handoff to a different console/terminal
_forceNoHandoff = true;
s_ConsumeArg(args, i);
hr = S_OK;
}
else if (arg == COM_SERVER_ARG)
{
_runAsComServer = true;
@@ -630,6 +640,11 @@ bool ConsoleArguments::GetForceV1() const
return _forceV1;
}
bool ConsoleArguments::GetForceNoHandoff() const
{
return _forceNoHandoff;
}
short ConsoleArguments::GetWidth() const
{
return _width;

View File

@@ -48,6 +48,7 @@ public:
std::wstring GetClientCommandline() const;
std::wstring GetVtMode() const;
bool GetForceV1() const;
bool GetForceNoHandoff() const;
short GetWidth() const;
short GetHeight() const;
@@ -68,6 +69,7 @@ public:
static const std::wstring_view HANDLE_PREFIX;
static const std::wstring_view CLIENT_COMMANDLINE_ARG;
static const std::wstring_view FORCE_V1_ARG;
static const std::wstring_view FORCE_NO_HANDOFF_ARG;
static const std::wstring_view FILEPATH_LEADER_PREFIX;
static const std::wstring_view WIDTH_ARG;
static const std::wstring_view HEIGHT_ARG;
@@ -89,6 +91,7 @@ private:
const short width,
const short height,
const bool forceV1,
const bool forceNoHandoff,
const bool headless,
const bool createServerHandle,
const DWORD serverHandle,
@@ -103,6 +106,7 @@ private:
_width(width),
_height(height),
_forceV1(forceV1),
_forceNoHandoff(forceNoHandoff),
_headless(headless),
_createServerHandle(createServerHandle),
_serverHandle(serverHandle),
@@ -127,6 +131,7 @@ private:
std::wstring _vtMode;
bool _forceNoHandoff;
bool _forceV1;
bool _headless;

View File

@@ -77,6 +77,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
true, // createServerHandle
0, // serverHandle
@@ -98,6 +99,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -119,6 +121,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
true, // createServerHandle
0, // serverHandle
@@ -140,6 +143,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
false, // createServerHandle
0x4, // serverHandle
@@ -161,6 +165,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
true, // createServerHandle
0, // serverHandle
@@ -182,6 +187,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -203,6 +209,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -224,6 +231,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -245,6 +253,7 @@ void ConsoleArgumentsTests::ArgSplittingTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -271,6 +280,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -292,6 +302,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -313,6 +324,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -334,6 +346,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -355,6 +368,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -376,6 +390,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -397,6 +412,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -418,6 +434,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
true, // createServerHandle
0, // serverHandle
@@ -439,6 +456,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -460,6 +478,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -486,6 +505,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -507,6 +527,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -528,6 +549,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -549,6 +571,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -570,6 +593,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -591,6 +615,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -612,6 +637,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
true, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -633,6 +659,51 @@ void ConsoleArgumentsTests::LegacyFormatsTests()
0, // width
0, // height
true, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
0, // signalHandle
false, // inheritCursor
false), // runAsComServer
true); // successful parse?
commandline = L"conhost.exe 0x4 -ForceNoHandoff";
ArgTestsRunner(L"#9 #7 Check that ConDrv handle + -ForceNoHandoff succeeds",
commandline,
INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE,
ConsoleArguments(commandline,
L"", // clientCommandLine
INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE,
L"", // vtMode
0, // width
0, // height
false, // forceV1
true, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
0, // signalHandle
false, // inheritCursor
false), // runAsComServer
true); // successful parse?
commandline = L"conhost.exe -ForceNoHandoff";
ArgTestsRunner(L"#10 Check that -ForceNoHandoff parses on its own",
commandline,
INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE,
ConsoleArguments(commandline,
L"", // clientCommandLine
INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE,
L"", // vtMode
0, // width
0, // height
false, // forceV1
true, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -683,6 +754,7 @@ void ConsoleArgumentsTests::CombineVtPipeHandleTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -704,6 +776,7 @@ void ConsoleArgumentsTests::CombineVtPipeHandleTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -740,6 +813,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
120, // width
30, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -761,6 +835,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
120, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -782,6 +857,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
0, // width
30, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -803,6 +879,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -824,6 +901,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
-1, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -845,6 +923,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -866,6 +945,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -887,6 +967,7 @@ void ConsoleArgumentsTests::InitialSizeTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -913,6 +994,7 @@ void ConsoleArgumentsTests::HeadlessArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
true, // createServerHandle
0, // serverHandle
@@ -934,6 +1016,7 @@ void ConsoleArgumentsTests::HeadlessArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -955,6 +1038,7 @@ void ConsoleArgumentsTests::HeadlessArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
true, // headless
true, // createServerHandle
0, // serverHandle
@@ -976,6 +1060,7 @@ void ConsoleArgumentsTests::HeadlessArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -1006,6 +1091,7 @@ void ConsoleArgumentsTests::SignalHandleTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -1027,6 +1113,7 @@ void ConsoleArgumentsTests::SignalHandleTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
false, // createServerHandle
4ul, // serverHandle
@@ -1048,6 +1135,7 @@ void ConsoleArgumentsTests::SignalHandleTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0ul, // serverHandle
@@ -1078,6 +1166,7 @@ void ConsoleArgumentsTests::FeatureArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -1098,6 +1187,7 @@ void ConsoleArgumentsTests::FeatureArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -1119,6 +1209,7 @@ void ConsoleArgumentsTests::FeatureArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -1140,6 +1231,7 @@ void ConsoleArgumentsTests::FeatureArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -1161,6 +1253,7 @@ void ConsoleArgumentsTests::FeatureArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle
@@ -1182,6 +1275,7 @@ void ConsoleArgumentsTests::FeatureArgTests()
0, // width
0, // height
false, // forceV1
false, // forceNoHandoff
false, // headless
true, // createServerHandle
0, // serverHandle

View File

@@ -159,6 +159,22 @@ static bool _shouldAttemptHandoff(const Globals& globals,
#else
// This console was started with a command line argument to
// specifically block handoff to another console. We presume
// this was for good reason (compatibility) and give up here.
if (globals.launchArgs.GetForceNoHandoff())
{
return false;
}
// Someone double clicked this console or explicitly tried
// to use it to launch a child process. Host it within this one
// and do not hand off.
if (globals.launchArgs.ShouldCreateServerHandle())
{
return false;
}
// This console is already initialized. Do not
// attempt handoff to another one.
// Note you can have a non-attach secondary connect for a child process