mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Shim the AzureConn through a conhost to stop VT bleeding (#4652)
This commit introduces a small console-subsystem application whose sole job is to consume TerminalConnection.dll and hook it up to something other than Terminal. It is 99% of the way to a generic solution. I've introduced a stopgap in TerminalPage that makes sure we launch TerminalAzBridge using ConptyConnection instead of AzureConnection. As a bonus, this commit includes a class whose sole job it is to make reading VT input off a console handle not terrible. It returns you a string and dispatches window size change callbacks. Fixes #2267. Fixes #4589. Related to #2266 (since pwsh needs better VT).
This commit is contained in:
parent
693cdc1c95
commit
7d6738cde7
@ -296,6 +296,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{D3EF
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winconpty.Tests.Feature", "src\winconpty\ft_pty\winconpty.FeatureTests.vcxproj", "{024052DE-83FB-4653-AEA4-90790D29D5BD}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winconpty.Tests.Feature", "src\winconpty\ft_pty\winconpty.FeatureTests.vcxproj", "{024052DE-83FB-4653-AEA4-90790D29D5BD}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAzBridge", "src\cascadia\TerminalAzBridge\TerminalAzBridge.vcxproj", "{067F0A06-FCB7-472C-96E9-B03B54E8E18D}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
AuditMode|Any CPU = AuditMode|Any CPU
|
AuditMode|Any CPU = AuditMode|Any CPU
|
||||||
@ -1435,6 +1437,20 @@ Global
|
|||||||
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x64.Build.0 = Release|x64
|
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x64.Build.0 = Release|x64
|
||||||
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.ActiveCfg = Release|Win32
|
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.Build.0 = Release|Win32
|
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x64.Build.0 = Release|x64
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -1510,6 +1526,7 @@ Global
|
|||||||
{6B5A44ED-918D-4747-BFB1-2472A1FCA173} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
|
{6B5A44ED-918D-4747-BFB1-2472A1FCA173} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
|
||||||
{D3EF7B96-CD5E-47C9-B9A9-136259563033} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
|
{D3EF7B96-CD5E-47C9-B9A9-136259563033} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
|
||||||
{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||||
|
{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
||||||
|
|||||||
@ -55,6 +55,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
|
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
|
||||||
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
|
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
|
||||||
|
<ProjectReference Include="..\TerminalAzBridge\TerminalAzBridge.vcxproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Target Name="OpenConsoleStompSourceProjectForWapProject" BeforeTargets="_ConvertItems">
|
<Target Name="OpenConsoleStompSourceProjectForWapProject" BeforeTargets="_ConvertItems">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -602,8 +602,10 @@ namespace winrt::TerminalApp::implementation
|
|||||||
profile->GetConnectionType() == AzureConnectionType &&
|
profile->GetConnectionType() == AzureConnectionType &&
|
||||||
TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
||||||
{
|
{
|
||||||
connection = TerminalConnection::AzureConnection(settings.InitialRows(),
|
// TODO GH#4661: Replace this with directly using the AzCon when our VT is better
|
||||||
settings.InitialCols());
|
std::filesystem::path azBridgePath{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
|
||||||
|
azBridgePath.replace_filename(L"TerminalAzBridge.exe");
|
||||||
|
connection = TerminalConnection::ConptyConnection(azBridgePath.wstring(), L".", L"Azure", settings.InitialRows(), settings.InitialCols(), winrt::guid());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (profile->HasConnectionType() &&
|
else if (profile->HasConnectionType() &&
|
||||||
|
|||||||
87
src/cascadia/TerminalAzBridge/ConsoleInputReader.cpp
Normal file
87
src/cascadia/TerminalAzBridge/ConsoleInputReader.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "ConsoleInputReader.h"
|
||||||
|
#include "unicode.hpp"
|
||||||
|
|
||||||
|
ConsoleInputReader::ConsoleInputReader(HANDLE handle) :
|
||||||
|
_handle(handle)
|
||||||
|
{
|
||||||
|
_buffer.resize(BufferSize);
|
||||||
|
_convertedString.reserve(BufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleInputReader::SetWindowSizeChangedCallback(std::function<void()> callback)
|
||||||
|
{
|
||||||
|
_windowSizeChangedCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::wstring_view> ConsoleInputReader::Read()
|
||||||
|
{
|
||||||
|
DWORD readCount{ 0 };
|
||||||
|
|
||||||
|
_convertedString.clear();
|
||||||
|
while (_convertedString.empty())
|
||||||
|
{
|
||||||
|
_buffer.resize(BufferSize);
|
||||||
|
BOOL succeeded =
|
||||||
|
ReadConsoleInputW(_handle, _buffer.data(), gsl::narrow_cast<DWORD>(_buffer.size()), &readCount);
|
||||||
|
if (!succeeded)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer.resize(readCount);
|
||||||
|
for (auto it = _buffer.begin(); it != _buffer.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->EventType == WINDOW_BUFFER_SIZE_EVENT && _windowSizeChangedCallback)
|
||||||
|
{
|
||||||
|
_windowSizeChangedCallback();
|
||||||
|
}
|
||||||
|
else if (it->EventType == KEY_EVENT)
|
||||||
|
{
|
||||||
|
const auto& keyEvent = it->Event.KeyEvent;
|
||||||
|
if (keyEvent.bKeyDown || (!keyEvent.bKeyDown && keyEvent.wVirtualKeyCode == VK_MENU))
|
||||||
|
{
|
||||||
|
// Got a high surrogate at the end of the buffer
|
||||||
|
if (IS_HIGH_SURROGATE(keyEvent.uChar.UnicodeChar))
|
||||||
|
{
|
||||||
|
_highSurrogate.emplace(keyEvent.uChar.UnicodeChar);
|
||||||
|
continue; // we've consumed it -- only dispatch it if we get a low
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_LOW_SURROGATE(keyEvent.uChar.UnicodeChar))
|
||||||
|
{
|
||||||
|
// No matter what we do, we want to destructively consume the high surrogate
|
||||||
|
if (const auto oldHighSurrogate{ std::exchange(_highSurrogate, std::nullopt) })
|
||||||
|
{
|
||||||
|
_convertedString.push_back(*_highSurrogate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we get a low without a high surrogate, we've done everything we can.
|
||||||
|
// This is an illegal state.
|
||||||
|
_convertedString.push_back(UNICODE_REPLACEMENT);
|
||||||
|
continue; // onto the next event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (\0 with a scancode is probably a modifier key, not a VT input key)
|
||||||
|
if (keyEvent.uChar.UnicodeChar != L'\0' || keyEvent.wVirtualScanCode == 0)
|
||||||
|
{
|
||||||
|
if (_highSurrogate) // non-destructive: we don't want to set it to nullopt needlessly for every character
|
||||||
|
{
|
||||||
|
// If we get a high surrogate *here*, we didn't find a low surrogate.
|
||||||
|
// This state is also illegal.
|
||||||
|
_convertedString.push_back(UNICODE_REPLACEMENT);
|
||||||
|
_highSurrogate.reset();
|
||||||
|
}
|
||||||
|
_convertedString.push_back(keyEvent.uChar.UnicodeChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _convertedString;
|
||||||
|
}
|
||||||
33
src/cascadia/TerminalAzBridge/ConsoleInputReader.h
Normal file
33
src/cascadia/TerminalAzBridge/ConsoleInputReader.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
ConsoleInputReader.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This file contains a class whose sole purpose is to
|
||||||
|
abstract away a bunch of details you usually need to
|
||||||
|
know to read VT from a console input handle.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
class ConsoleInputReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConsoleInputReader(HANDLE handle);
|
||||||
|
void SetWindowSizeChangedCallback(std::function<void()> callback);
|
||||||
|
std::optional<std::wstring_view> Read();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr size_t BufferSize{ 128 };
|
||||||
|
|
||||||
|
HANDLE _handle;
|
||||||
|
std::wstring _convertedString;
|
||||||
|
std::vector<INPUT_RECORD> _buffer;
|
||||||
|
std::optional<wchar_t> _highSurrogate;
|
||||||
|
std::function<void()> _windowSizeChangedCallback;
|
||||||
|
};
|
||||||
71
src/cascadia/TerminalAzBridge/TerminalAzBridge.vcxproj
Normal file
71
src/cascadia/TerminalAzBridge/TerminalAzBridge.vcxproj
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?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>{067F0A06-FCB7-472C-96E9-B03B54E8E18D}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>TerminalAzBridge</RootNamespace>
|
||||||
|
<ProjectName>TerminalAzBridge</ProjectName>
|
||||||
|
<TargetName>TerminalAzBridge</TargetName>
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
|
||||||
|
<ApplicationType>Windows Store</ApplicationType>
|
||||||
|
<NoOutputRedirection>true</NoOutputRedirection>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||||
|
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||||
|
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<GenerateManifest>true</GenerateManifest>
|
||||||
|
<EmbedManifest>true</EmbedManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- Source Files -->
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="pch.h" />
|
||||||
|
<ClInclude Include="ConsoleInputReader.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="ConsoleInputReader.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<!-- Dependencies -->
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj">
|
||||||
|
<Project>{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This ItemGroup and the Globals PropertyGroup below it are required in order
|
||||||
|
to enable F5 debugging for the unpackaged application
|
||||||
|
-->
|
||||||
|
<ItemGroup>
|
||||||
|
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\debugger_general.xml" />
|
||||||
|
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\debugger_local_windows.xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||||
|
|
||||||
|
<Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" />
|
||||||
|
</Project>
|
||||||
104
src/cascadia/TerminalAzBridge/main.cpp
Normal file
104
src/cascadia/TerminalAzBridge/main.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "winrt/Microsoft.Terminal.TerminalConnection.h"
|
||||||
|
#include "ConsoleInputReader.h"
|
||||||
|
|
||||||
|
using namespace winrt;
|
||||||
|
using namespace winrt::Windows::Foundation;
|
||||||
|
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||||
|
|
||||||
|
static COORD GetConsoleScreenSize(HANDLE outputHandle)
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
|
||||||
|
csbiex.cbSize = sizeof(csbiex);
|
||||||
|
GetConsoleScreenBufferInfoEx(outputHandle, &csbiex);
|
||||||
|
return {
|
||||||
|
(csbiex.srWindow.Right - csbiex.srWindow.Left) + 1,
|
||||||
|
(csbiex.srWindow.Bottom - csbiex.srWindow.Top) + 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ConnectionState RunConnectionToCompletion(const ITerminalConnection& connection, HANDLE outputHandle, HANDLE inputHandle)
|
||||||
|
{
|
||||||
|
connection.TerminalOutput([outputHandle](const winrt::hstring& output) {
|
||||||
|
WriteConsoleW(outputHandle, output.data(), output.size(), nullptr, nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Detach a thread to spin the console read indefinitely.
|
||||||
|
// This application exits when the connection is closed, so
|
||||||
|
// the connection's lifetime will outlast this thread.
|
||||||
|
std::thread([connection, outputHandle, inputHandle] {
|
||||||
|
ConsoleInputReader reader{ inputHandle };
|
||||||
|
reader.SetWindowSizeChangedCallback([&]() {
|
||||||
|
const auto size = GetConsoleScreenSize(outputHandle);
|
||||||
|
|
||||||
|
connection.Resize(size.Y, size.X);
|
||||||
|
});
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto input = reader.Read();
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
connection.WriteInput(*input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).detach();
|
||||||
|
|
||||||
|
std::condition_variable stateChangeVar;
|
||||||
|
std::optional<ConnectionState> state;
|
||||||
|
std::mutex stateMutex;
|
||||||
|
|
||||||
|
connection.StateChanged([&](auto&& /*s*/, auto&& /*e*/) {
|
||||||
|
std::unique_lock<std::mutex> lg{ stateMutex };
|
||||||
|
state = connection.State();
|
||||||
|
stateChangeVar.notify_all();
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.Start();
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lg{ stateMutex };
|
||||||
|
stateChangeVar.wait(lg, [&]() {
|
||||||
|
if (!state.has_value())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return state.value() == ConnectionState::Closed || state.value() == ConnectionState::Failed;
|
||||||
|
});
|
||||||
|
|
||||||
|
return state.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
int wmain(int /*argc*/, wchar_t** /*argv*/)
|
||||||
|
{
|
||||||
|
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
||||||
|
|
||||||
|
DWORD inputMode{}, outputMode{};
|
||||||
|
HANDLE conIn{ GetStdHandle(STD_INPUT_HANDLE) }, conOut{ GetStdHandle(STD_OUTPUT_HANDLE) };
|
||||||
|
UINT codepage{ GetConsoleCP() }, outputCodepage{ GetConsoleOutputCP() };
|
||||||
|
|
||||||
|
RETURN_IF_WIN32_BOOL_FALSE(GetConsoleMode(conIn, &inputMode));
|
||||||
|
RETURN_IF_WIN32_BOOL_FALSE(GetConsoleMode(conOut, &outputMode));
|
||||||
|
|
||||||
|
RETURN_IF_WIN32_BOOL_FALSE(SetConsoleMode(conIn, ENABLE_WINDOW_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT));
|
||||||
|
RETURN_IF_WIN32_BOOL_FALSE(SetConsoleMode(conOut, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_WRAP_AT_EOL_OUTPUT | DISABLE_NEWLINE_AUTO_RETURN));
|
||||||
|
RETURN_IF_WIN32_BOOL_FALSE(SetConsoleCP(CP_UTF8));
|
||||||
|
RETURN_IF_WIN32_BOOL_FALSE(SetConsoleOutputCP(CP_UTF8));
|
||||||
|
|
||||||
|
auto restoreConsoleModes = wil::scope_exit([&]() {
|
||||||
|
SetConsoleMode(conIn, inputMode);
|
||||||
|
SetConsoleMode(conOut, outputMode);
|
||||||
|
SetConsoleCP(codepage);
|
||||||
|
SetConsoleOutputCP(outputCodepage);
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto size = GetConsoleScreenSize(conOut);
|
||||||
|
|
||||||
|
AzureConnection azureConn{ gsl::narrow_cast<uint32_t>(size.Y), gsl::narrow_cast<uint32_t>(size.X) };
|
||||||
|
|
||||||
|
const auto state = RunConnectionToCompletion(azureConn, conOut, conIn);
|
||||||
|
|
||||||
|
return state == ConnectionState::Closed ? 0 : 1;
|
||||||
|
}
|
||||||
4
src/cascadia/TerminalAzBridge/packages.config
Normal file
4
src/cascadia/TerminalAzBridge/packages.config
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||||
|
</packages>
|
||||||
4
src/cascadia/TerminalAzBridge/pch.cpp
Normal file
4
src/cascadia/TerminalAzBridge/pch.cpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
36
src/cascadia/TerminalAzBridge/pch.h
Normal file
36
src/cascadia/TerminalAzBridge/pch.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*++
|
||||||
|
Copyright (c) Microsoft Corporation
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
- pch.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
- Contains external headers to include in the precompile phase of console build process.
|
||||||
|
- Avoid including internal project headers. Instead include them only in the classes that need them (helps with test project building).
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Ignore checked iterators warning from VC compiler.
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
|
// Block minwindef.h min/max macros to prevent <algorithm> conflict
|
||||||
|
#define NOMINMAX
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <unknwn.h>
|
||||||
|
|
||||||
|
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "../inc/LibraryIncludes.h"
|
||||||
|
|
||||||
|
#include <wil/cppwinrt.h>
|
||||||
|
|
||||||
|
#include <winrt/Windows.system.h>
|
||||||
|
#include <winrt/Windows.Foundation.Collections.h>
|
||||||
|
|
||||||
|
#include <wil/resource.h>
|
||||||
|
#include <wil/win32_helpers.h>
|
||||||
Loading…
x
Reference in New Issue
Block a user