mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Wire up passing LNK/EXE data from OpenCon to ITerminalHandoff (#13570)
This PR by itself doesn't _really_ change much. Technically, now the Terminal will respect the Title of a `.lnk` when started for defterm, but we don't do anything else yet. Primarily, the goal of this PR is to just wire up startup info in OpenConsole to the connected Terminal. * This required a bit of changes in `srvinit.cpp:ConsoleEstablishHandoff` to replicate other bits of startup, where we crack open the connect message to get the relevant bits of info. * We pack that all into a `TERMINAL_STARTUP_INFO`, which we pass along to the registered terminal application. * `ConptyConnection` accepts the handoff, and gathers that information out of the `TERMINAL_STARTUP_INFO` * Some other updates to the scratch sln were made to make it build again (related, but unimportant). * This is a precursor to: * #13111 * #12154 * Closes #9458 * Tested manually * I work here
This commit is contained in:
parent
deb5e7c650
commit
7e47f6aab9
@ -17,9 +17,15 @@
|
||||
<DisableEmbeddedXbf>false</DisableEmbeddedXbf>
|
||||
<XamlComponentResourceLocation>nested</XamlComponentResourceLocation>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
<ClCompile>
|
||||
@ -147,14 +153,15 @@
|
||||
<!-- ========================= Globals ======================== -->
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
|
||||
@ -11,9 +11,13 @@
|
||||
<!-- sets a bunch of Windows Universal properties -->
|
||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<!-- ========================= XAML files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- DON'T PUT XAML FILES HERE! Put them in SampleAppLib.vcxproj -->
|
||||
@ -79,15 +83,20 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ====================== Compiler & Linker Flags ===================== -->
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\ConTypes.lib;WindowsApp.lib;shell32.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
@ -102,4 +111,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
</Project>
|
||||
|
||||
@ -104,8 +104,6 @@ void SampleIslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam)
|
||||
|
||||
void SampleIslandWindow::Initialize()
|
||||
{
|
||||
const bool initialized = (_interopWindowHandle != nullptr);
|
||||
|
||||
_source = DesktopWindowXamlSource{};
|
||||
|
||||
auto interop = _source.as<IDesktopWindowXamlSourceNative>();
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{b4427499-9fde-4208-b456-5bc580637633}</ProjectGuid>
|
||||
@ -16,7 +15,15 @@
|
||||
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
|
||||
<TerminalVCRTForwarders>true</TerminalVCRTForwarders>
|
||||
<TerminalThemeHelpers>true</TerminalThemeHelpers>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
@ -138,16 +145,11 @@
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!-- Override GetPackagingOutputs to roll up all our dependencies.
|
||||
@ -225,13 +227,24 @@
|
||||
<TargetPath>%(Filename)%(Extension)</TargetPath>
|
||||
</PackagingOutputs>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Same thing AGAIN here, with OpenConsole.exe If you forget this, then
|
||||
the scratch app will use the inbox conpty with a newer conpty lib, causing
|
||||
us to send the inbox conhost messages that will make it explode. -->
|
||||
<ItemGroup>
|
||||
<_OpenConsoleExe Include="$(OpenConsoleCommonOutDir)\OpenConsole.exe" />
|
||||
|
||||
<PackagingOutputs Include="@(_OpenConsoleExe)">
|
||||
<ProjectName>$(ProjectName)</ProjectName>
|
||||
<OutputGroup>BuiltProjectOutputGroup</OutputGroup>
|
||||
<TargetPath>%(Filename)%(Extension)</TargetPath>
|
||||
</PackagingOutputs>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" />
|
||||
<Import Project="..\..\..\packages\Terminal.ThemeHelpers.0.2.200324001\build\native\Terminal.ThemeHelpers.targets" Condition="Exists('..\..\..\packages\Terminal.ThemeHelpers.0.2.200324001\build\native\Terminal.ThemeHelpers.targets')" />
|
||||
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
</Project>
|
||||
|
||||
|
||||
@ -99,7 +99,8 @@
|
||||
<com:ComInterface>
|
||||
<com:ProxyStub Id="DEC4804D-56D1-4F73-9FBE-6828E7C85C56" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/> <!-- ITerminalHandoff -->
|
||||
<com:Interface Id="AA6B364F-4A50-4176-9002-0AE755E7B5EF" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/> <!-- ITerminalHandoff2 -->
|
||||
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
|
||||
@ -188,7 +188,8 @@
|
||||
<com:ComInterface>
|
||||
<com:ProxyStub Id="1833E661-CC81-4DD0-87C6-C2F74BD39EFA" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/> <!-- ITerminalHandoff -->
|
||||
<com:Interface Id="AA6B364F-4A50-4176-9002-0AE755E7B5EF" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/> <!-- ITerminalHandoff2 -->
|
||||
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
|
||||
@ -188,7 +188,8 @@
|
||||
<com:ComInterface>
|
||||
<com:ProxyStub Id="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/> <!-- ITerminalHandoff -->
|
||||
<com:Interface Id="AA6B364F-4A50-4176-9002-0AE755E7B5EF" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/> <!-- ITerminalHandoff2 -->
|
||||
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
|
||||
@ -3270,6 +3270,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
NewTerminalArgs newTerminalArgs;
|
||||
newTerminalArgs.Commandline(connection.Commandline());
|
||||
newTerminalArgs.TabTitle(connection.StartingTitle());
|
||||
// GH #12370: We absolutely cannot allow a defterm connection to
|
||||
// auto-elevate. Defterm doesn't work for elevated scenarios in the
|
||||
// first place. If we try accepting the connection, the spawning an
|
||||
|
||||
@ -102,7 +102,7 @@ static HRESULT _duplicateHandle(const HANDLE in, HANDLE& out) noexcept
|
||||
// - E_NOT_VALID_STATE if a event handler is not registered before calling. `::DuplicateHandle`
|
||||
// error codes if we cannot manage to make our own copy of handles to retain. Or S_OK/error
|
||||
// from the registered handler event function.
|
||||
HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client)
|
||||
HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client, TERMINAL_STARTUP_INFO startupInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -132,7 +132,7 @@ HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE in, HANDLE out, HANDLE sign
|
||||
THROW_IF_FAILED(_duplicateHandle(client, client));
|
||||
|
||||
// Call registered handler from when we started listening.
|
||||
THROW_IF_FAILED(localPfnHandoff(in, out, signal, ref, server, client));
|
||||
THROW_IF_FAILED(localPfnHandoff(in, out, signal, ref, server, client, startupInfo));
|
||||
|
||||
#pragma warning(suppress : 26477)
|
||||
TraceLoggingWrite(
|
||||
|
||||
@ -26,10 +26,10 @@ Author(s):
|
||||
#define __CLSID_CTerminalHandoff "051F34EE-C1FD-4B19-AF75-9BA54648434C"
|
||||
#endif
|
||||
|
||||
using NewHandoffFunction = HRESULT (*)(HANDLE, HANDLE, HANDLE, HANDLE, HANDLE, HANDLE);
|
||||
using NewHandoffFunction = HRESULT (*)(HANDLE, HANDLE, HANDLE, HANDLE, HANDLE, HANDLE, TERMINAL_STARTUP_INFO);
|
||||
|
||||
struct __declspec(uuid(__CLSID_CTerminalHandoff))
|
||||
CTerminalHandoff : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, ITerminalHandoff>
|
||||
CTerminalHandoff : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, ITerminalHandoff2>
|
||||
{
|
||||
#pragma region ITerminalHandoff
|
||||
STDMETHODIMP EstablishPtyHandoff(HANDLE in,
|
||||
@ -37,7 +37,8 @@ struct __declspec(uuid(__CLSID_CTerminalHandoff))
|
||||
HANDLE signal,
|
||||
HANDLE ref,
|
||||
HANDLE server,
|
||||
HANDLE client) override;
|
||||
HANDLE client,
|
||||
TERMINAL_STARTUP_INFO startupInfo) override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
@ -203,7 +203,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
const HANDLE hOut,
|
||||
const HANDLE hRef,
|
||||
const HANDLE hServerProcess,
|
||||
const HANDLE hClientProcess) :
|
||||
const HANDLE hClientProcess,
|
||||
TERMINAL_STARTUP_INFO startupInfo) :
|
||||
_initialRows{ 25 },
|
||||
_initialCols{ 80 },
|
||||
_guid{ Utils::CreateGuid() },
|
||||
@ -213,6 +214,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
THROW_IF_FAILED(ConptyPackPseudoConsole(hServerProcess, hRef, hSig, &_hPC));
|
||||
_piClient.hProcess = hClientProcess;
|
||||
|
||||
_startupInfo.title = winrt::hstring{ startupInfo.pszTitle, SysStringLen(startupInfo.pszTitle) };
|
||||
SysFreeString(startupInfo.pszTitle);
|
||||
_startupInfo.iconPath = winrt::hstring{ startupInfo.pszIconPath, SysStringLen(startupInfo.pszIconPath) };
|
||||
SysFreeString(startupInfo.pszIconPath);
|
||||
_startupInfo.iconIndex = startupInfo.iconIndex;
|
||||
|
||||
try
|
||||
{
|
||||
_commandline = _commandlineFromProcess(hClientProcess);
|
||||
@ -288,6 +295,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
return _commandline;
|
||||
}
|
||||
|
||||
winrt::hstring ConptyConnection::StartingTitle() const
|
||||
{
|
||||
return _startupInfo.title;
|
||||
}
|
||||
|
||||
void ConptyConnection::Start()
|
||||
try
|
||||
{
|
||||
@ -667,10 +679,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
winrt::event_token ConptyConnection::NewConnection(const NewConnectionHandler& handler) { return _newConnectionHandlers.add(handler); };
|
||||
void ConptyConnection::NewConnection(const winrt::event_token& token) { _newConnectionHandlers.remove(token); };
|
||||
|
||||
HRESULT ConptyConnection::NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client) noexcept
|
||||
HRESULT ConptyConnection::NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client, TERMINAL_STARTUP_INFO startupInfo) noexcept
|
||||
try
|
||||
{
|
||||
_newConnectionHandlers(winrt::make<ConptyConnection>(signal, in, out, ref, server, client));
|
||||
_newConnectionHandlers(winrt::make<ConptyConnection>(signal, in, out, ref, server, client, startupInfo));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
|
||||
#include <conpty-static.h>
|
||||
|
||||
#include "ITerminalHandoff.h"
|
||||
|
||||
namespace wil
|
||||
{
|
||||
// These belong in WIL upstream, so when we reingest the change that has them we'll get rid of ours.
|
||||
@ -23,7 +25,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
const HANDLE hOut,
|
||||
const HANDLE hRef,
|
||||
const HANDLE hServerProcess,
|
||||
const HANDLE hClientProcess);
|
||||
const HANDLE hClientProcess,
|
||||
TERMINAL_STARTUP_INFO startupInfo);
|
||||
|
||||
ConptyConnection() noexcept = default;
|
||||
void Initialize(const Windows::Foundation::Collections::ValueSet& settings);
|
||||
@ -42,6 +45,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
winrt::guid Guid() const noexcept;
|
||||
winrt::hstring Commandline() const;
|
||||
winrt::hstring StartingTitle() const;
|
||||
|
||||
static void StartInboundListener();
|
||||
static void StopInboundListener();
|
||||
@ -60,7 +64,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
||||
|
||||
private:
|
||||
static HRESULT NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client) noexcept;
|
||||
static HRESULT NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client, TERMINAL_STARTUP_INFO startupInfo) noexcept;
|
||||
static winrt::hstring _commandlineFromProcess(HANDLE process);
|
||||
|
||||
HRESULT _LaunchAttachedClient() noexcept;
|
||||
@ -93,6 +97,14 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
std::array<char, 4096> _buffer{};
|
||||
bool _passthroughMode{};
|
||||
|
||||
struct StartupInfoFromDefTerm
|
||||
{
|
||||
winrt::hstring title{};
|
||||
winrt::hstring iconPath{};
|
||||
int32_t iconIndex{};
|
||||
|
||||
} _startupInfo{};
|
||||
|
||||
DWORD _OutputThread();
|
||||
};
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ namespace Microsoft.Terminal.TerminalConnection
|
||||
ConptyConnection();
|
||||
Guid Guid { get; };
|
||||
String Commandline { get; };
|
||||
String StartingTitle { get; };
|
||||
|
||||
void ClearBuffer();
|
||||
|
||||
|
||||
@ -4,11 +4,41 @@
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
|
||||
|
||||
typedef struct _TERMINAL_STARTUP_INFO
|
||||
{
|
||||
// In STARTUPINFO
|
||||
BSTR pszTitle;
|
||||
|
||||
// Also wanted
|
||||
BSTR pszIconPath;
|
||||
LONG iconIndex;
|
||||
|
||||
// The rest of STARTUPINFO
|
||||
DWORD dwX;
|
||||
DWORD dwY;
|
||||
DWORD dwXSize;
|
||||
DWORD dwYSize;
|
||||
DWORD dwXCountChars;
|
||||
DWORD dwYCountChars;
|
||||
DWORD dwFillAttribute;
|
||||
DWORD dwFlags;
|
||||
WORD wShowWindow;
|
||||
} TERMINAL_STARTUP_INFO;
|
||||
|
||||
// LOAD BEARING!
|
||||
//
|
||||
// There is only ever one OpenConsoleProxy.dll loaded by COM for _ALL_ terminal
|
||||
// instances, across Dev, Preview, Stable, whatever. So we have to keep all old
|
||||
// versions of interfaces in the file here, even if the old version is no longer
|
||||
// in use.
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(59D55CCE-FC8A-48B4-ACE8-0A9286C6557F)
|
||||
] interface ITerminalHandoff : IUnknown
|
||||
{
|
||||
// DEPRECATED!
|
||||
HRESULT EstablishPtyHandoff([in, system_handle(sh_pipe)] HANDLE in,
|
||||
[in, system_handle(sh_pipe)] HANDLE out,
|
||||
[in, system_handle(sh_pipe)] HANDLE signal,
|
||||
@ -16,3 +46,17 @@ import "ocidl.idl";
|
||||
[in, system_handle(sh_process)] HANDLE server,
|
||||
[in, system_handle(sh_process)] HANDLE client);
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(AA6B364F-4A50-4176-9002-0AE755E7B5EF)
|
||||
] interface ITerminalHandoff2 : IUnknown
|
||||
{
|
||||
HRESULT EstablishPtyHandoff([in, system_handle(sh_pipe)] HANDLE in,
|
||||
[in, system_handle(sh_pipe)] HANDLE out,
|
||||
[in, system_handle(sh_pipe)] HANDLE signal,
|
||||
[in, system_handle(sh_file)] HANDLE ref,
|
||||
[in, system_handle(sh_process)] HANDLE server,
|
||||
[in, system_handle(sh_process)] HANDLE client,
|
||||
[in] TERMINAL_STARTUP_INFO startupInfo);
|
||||
};
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "../server/Entrypoints.h"
|
||||
#include "../server/IoSorter.h"
|
||||
|
||||
#include "../interactivity/inc/ISystemConfigurationProvider.hpp"
|
||||
#include "../interactivity/inc/ServiceLocator.hpp"
|
||||
#include "../interactivity/base/ApiDetector.hpp"
|
||||
#include "../interactivity/base/RemoteConsoleControl.hpp"
|
||||
@ -179,7 +180,7 @@ static bool s_IsOnDesktop()
|
||||
|
||||
// We need to see if we were spawned from a link. If we were, we need to
|
||||
// call back into the shell to try to get all the console information from the link.
|
||||
ServiceLocator::LocateSystemConfigurationProvider()->GetSettingsFromLink(&settings, Title, &TitleLength, CurDir, AppName);
|
||||
ServiceLocator::LocateSystemConfigurationProvider()->GetSettingsFromLink(&settings, Title, &TitleLength, CurDir, AppName, nullptr);
|
||||
|
||||
// If we weren't started from a link, this will already be set.
|
||||
// If LoadLinkInfo couldn't find anything, it will remove the flag so we can dig in the registry.
|
||||
@ -198,6 +199,22 @@ static bool s_IsOnDesktop()
|
||||
// strong nudge in that direction. If an application _doesn't_ want VT
|
||||
// processing, it's free to disable this setting, even in conpty mode.
|
||||
settings.SetVirtTermLevel(1);
|
||||
|
||||
// GH#9458 - In the case of a DefTerm handoff, the OriginalTitle might
|
||||
// be stashed in the lnk. We want to crack that lnk open, so we can get
|
||||
// that title from it, but we want to discard everything else. So build
|
||||
// a dummy Settings object here, and read the link settings into it.
|
||||
// `Title` will get filled with the title from the lnk, which we'll use
|
||||
// below.
|
||||
|
||||
Settings temp;
|
||||
// We're not gonna copy over StartupFlags to the main gci settings,
|
||||
// because we generally don't think those are valuable in ConPTY mode.
|
||||
// However, we do need to apply them to the temp we've created, so that
|
||||
// GetSettingsFromLink will actually look for the link settings (it will
|
||||
// skip that if STARTF_TITLEISLINKNAME is not set).
|
||||
temp.SetStartupFlags(pStartupSettings->GetStartupFlags());
|
||||
ServiceLocator::LocateSystemConfigurationProvider()->GetSettingsFromLink(&temp, Title, &TitleLength, CurDir, AppName, nullptr);
|
||||
}
|
||||
|
||||
// 1. The settings we were passed contains STARTUPINFO structure settings to be applied last.
|
||||
@ -494,7 +511,7 @@ try
|
||||
|
||||
const auto serverProcess = GetCurrentProcess();
|
||||
|
||||
::Microsoft::WRL::ComPtr<ITerminalHandoff> handoff;
|
||||
::Microsoft::WRL::ComPtr<ITerminalHandoff2> handoff;
|
||||
|
||||
TraceLoggingWrite(g_hConhostV2EventTraceProvider,
|
||||
"SrvInit_PrepareToCreateDelegationTerminal",
|
||||
@ -509,12 +526,71 @@ try
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||
|
||||
// As a part of defterm handoff, we're gonna try to pull a lot of
|
||||
// information out of the link and startup info, so we can let the terminal
|
||||
// know these things as well.
|
||||
//
|
||||
// To let the terminal know these things, we have to look them up now,
|
||||
// before we normally would.
|
||||
//
|
||||
// Typically, we'll just go into `ConsoleCreateIoThread` below, which will
|
||||
// pull out the CONSOLE_API_CONNECTINFO from this connect message, and then
|
||||
// get the link properties out of the title later. Below are elements of
|
||||
// ConsoleAllocateConsole and SetUpConsole that get the bits of STARTUP_INFO
|
||||
// we care about for defterm handoffs.
|
||||
|
||||
// A placeholder that we'll read icon information into, instead of setting
|
||||
// the globals icon state.
|
||||
Microsoft::Console::Interactivity::IconInfo icon;
|
||||
|
||||
// To be able to actually process this connect message into a
|
||||
// CONSOLE_API_CONNECTINFO, we need to hook up the ConDrvDeviceComm to the
|
||||
// message. Usually, we'd create the ConDrvDeviceComm later, in
|
||||
// ConsoleServerInitialization, but we can set it up early here.
|
||||
// ConsoleServerInitialization will safely no-op if it already finds one.
|
||||
g.pDeviceComm = new ConDrvDeviceComm(Server);
|
||||
// load bearing: if you don't set this, the ConsoleInitializeConnectInfo will fail.
|
||||
connectMessage->_pDeviceComm = g.pDeviceComm;
|
||||
CONSOLE_API_CONNECTINFO Cac;
|
||||
RETURN_IF_NTSTATUS_FAILED(ConsoleInitializeConnectInfo(connectMessage, &Cac));
|
||||
|
||||
// BEGIN code from SetUpConsole
|
||||
// Create a temporary Settings object to parse the settings into, rather
|
||||
// than parsing them into the global settings object (gci).
|
||||
Settings settings{};
|
||||
// We need to see if we were spawned from a link. If we were, we need to
|
||||
// call back into the OS shell to try to get all the console information from the link.
|
||||
//
|
||||
// load bearing: if you don't pass the StartupFlags, then
|
||||
// GetSettingsFromLink might not even bother attempting to check the lnk.
|
||||
settings.SetStartupFlags(Cac.ConsoleInfo.GetStartupFlags());
|
||||
ServiceLocator::LocateSystemConfigurationProvider()->GetSettingsFromLink(&settings,
|
||||
Cac.Title,
|
||||
&Cac.TitleLength,
|
||||
Cac.CurDir,
|
||||
Cac.AppName,
|
||||
&icon);
|
||||
|
||||
// 1. The settings we were passed contains STARTUPINFO structure settings to be applied last.
|
||||
settings.ApplyStartupInfo(&Cac.ConsoleInfo);
|
||||
// END code from SetUpConsole
|
||||
|
||||
// Take what we've collected, and bundle it up for handoff.
|
||||
auto title = wil::make_bstr(Cac.Title);
|
||||
auto iconPath = wil::make_bstr(icon.path.data());
|
||||
TERMINAL_STARTUP_INFO myStartupInfo{
|
||||
title.get(),
|
||||
iconPath.get(),
|
||||
icon.index
|
||||
};
|
||||
|
||||
RETURN_IF_FAILED(handoff->EstablishPtyHandoff(inPipeTheirSide.get(),
|
||||
outPipeTheirSide.get(),
|
||||
signalPipeTheirSide.get(),
|
||||
refHandle.get(),
|
||||
serverProcess,
|
||||
clientProcess.get()));
|
||||
clientProcess.get(),
|
||||
myStartupInfo));
|
||||
|
||||
TraceLoggingWrite(g_hConhostV2EventTraceProvider,
|
||||
"SrvInit_DelegateToTerminalSucceeded",
|
||||
|
||||
@ -19,6 +19,12 @@ class Settings;
|
||||
|
||||
namespace Microsoft::Console::Interactivity
|
||||
{
|
||||
struct IconInfo
|
||||
{
|
||||
std::wstring path;
|
||||
int index = 0;
|
||||
};
|
||||
|
||||
class ISystemConfigurationProvider
|
||||
{
|
||||
public:
|
||||
@ -36,6 +42,7 @@ namespace Microsoft::Console::Interactivity
|
||||
_Inout_updates_bytes_(*pdwTitleLength) LPWSTR pwszTitle,
|
||||
_Inout_ PDWORD pdwTitleLength,
|
||||
_In_ PCWSTR pwszCurrDir,
|
||||
_In_ PCWSTR pwszAppName) = 0;
|
||||
_In_ PCWSTR pwszAppName,
|
||||
_Inout_opt_ IconInfo* iconInfo) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@ -49,7 +49,8 @@ void SystemConfigurationProvider::GetSettingsFromLink(
|
||||
_Inout_updates_bytes_(*pdwTitleLength) LPWSTR /*pwszTitle*/,
|
||||
_Inout_ PDWORD /*pdwTitleLength*/,
|
||||
_In_ PCWSTR /*pwszCurrDir*/,
|
||||
_In_ PCWSTR /*pwszAppName*/)
|
||||
_In_ PCWSTR /*pwszAppName*/,
|
||||
_Inout_opt_ IconInfo* /*iconInfo*/)
|
||||
{
|
||||
// While both OneCore console renderers use TrueType fonts, there is no
|
||||
// advanced font support on that platform. Namely, there is no way to pick
|
||||
|
||||
@ -37,7 +37,8 @@ namespace Microsoft::Console::Interactivity::OneCore
|
||||
_Inout_updates_bytes_(*pdwTitleLength) LPWSTR pwszTitle,
|
||||
_Inout_ PDWORD pdwTitleLength,
|
||||
_In_ PCWSTR pwszCurrDir,
|
||||
_In_ PCWSTR pwszAppName) override;
|
||||
_In_ PCWSTR pwszAppName,
|
||||
_Inout_opt_ IconInfo* iconInfo) override;
|
||||
|
||||
private:
|
||||
static constexpr UINT s_DefaultCaretBlinkTime = 530; // milliseconds
|
||||
|
||||
@ -60,7 +60,8 @@ void SystemConfigurationProvider::GetSettingsFromLink(
|
||||
_Inout_updates_bytes_(*pdwTitleLength) LPWSTR pwszTitle,
|
||||
_Inout_ PDWORD pdwTitleLength,
|
||||
_In_ PCWSTR pwszCurrDir,
|
||||
_In_ PCWSTR pwszAppName)
|
||||
_In_ PCWSTR pwszAppName,
|
||||
_Inout_opt_ IconInfo* iconInfo)
|
||||
{
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
WCHAR wszLinkTarget[MAX_PATH] = { 0 };
|
||||
@ -72,8 +73,15 @@ void SystemConfigurationProvider::GetSettingsFromLink(
|
||||
// Did we get started from a link?
|
||||
if (pLinkSettings->GetStartupFlags() & STARTF_TITLEISLINKNAME)
|
||||
{
|
||||
if (SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)))
|
||||
auto initializedCom = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||
|
||||
// GH#9458: If it's RPC_E_CHANGED_MODE, that's okay, we're doing a
|
||||
// defterm and have already started COM. We can continue on here.
|
||||
if (SUCCEEDED(initializedCom) || initializedCom == RPC_E_CHANGED_MODE)
|
||||
{
|
||||
// Don't CoUninitialize if we still need COM for defterm.
|
||||
auto unInitCom = wil::scope_exit([initializedCom]() { if (SUCCEEDED(initializedCom)){CoUninitialize();} });
|
||||
|
||||
const auto cch = *pdwTitleLength / sizeof(wchar_t);
|
||||
|
||||
gci.SetLinkTitle(std::wstring(pwszTitle, cch));
|
||||
@ -156,7 +164,6 @@ void SystemConfigurationProvider::GetSettingsFromLink(
|
||||
// settings based on title.
|
||||
pLinkSettings->UnsetStartupFlag(STARTF_TITLEISLINKNAME);
|
||||
}
|
||||
CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +198,19 @@ void SystemConfigurationProvider::GetSettingsFromLink(
|
||||
|
||||
if (wszIconLocation[0] != L'\0')
|
||||
{
|
||||
LOG_IF_FAILED(Icon::Instance().LoadIconsFromPath(wszIconLocation, iIconIndex));
|
||||
// GH#9458, GH#13111 - when this is executed during defterm startup,
|
||||
// we'll pass in an iconInfo pointer, which we should fill with the
|
||||
// selected icon path and index, rather than loading the icon with our
|
||||
// global Icon class.
|
||||
if (iconInfo)
|
||||
{
|
||||
iconInfo->path = std::wstring{ wszIconLocation };
|
||||
iconInfo->index = iIconIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_IF_FAILED(Icon::Instance().LoadIconsFromPath(wszIconLocation, iIconIndex));
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsValidCodePage(pLinkSettings->GetCodePage()))
|
||||
|
||||
@ -37,7 +37,8 @@ namespace Microsoft::Console::Interactivity::Win32
|
||||
_Inout_updates_bytes_(*pdwTitleLength) LPWSTR pwszTitle,
|
||||
_Inout_ PDWORD pdwTitleLength,
|
||||
_In_ PCWSTR pwszCurrDir,
|
||||
_In_ PCWSTR pwszAppName);
|
||||
_In_ PCWSTR pwszAppName,
|
||||
_Inout_opt_ IconInfo* iconInfo);
|
||||
|
||||
private:
|
||||
static const ULONG s_DefaultCursorWidth = 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user