From 487adccdde08ed875199b06a9e2da7a34967e359 Mon Sep 17 00:00:00 2001 From: xiangb-a Date: Mon, 11 Aug 2025 15:15:03 +0800 Subject: [PATCH 1/2] We should check in advance whether we are using a console program. If we are not using a console program, setting the input and output language of Console will have no effect and will throw an exception. For example, when using WPF, an exception will be thrown here, causing the connection to fail --- .../Client/StdioClientTransport.cs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs index c026acb9..c828dfc2 100644 --- a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs +++ b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs @@ -156,20 +156,21 @@ public async Task ConnectAsync(CancellationToken cancellationToken = // up the encoding from Console.InputEncoding. As such, when not targeting .NET Core, // we temporarily change Console.InputEncoding to no-BOM UTF-8 around the Process.Start // call, to ensure it picks up the correct encoding. -#if NET - processStarted = process.Start(); -#else +#if !NET Encoding originalInputEncoding = Console.InputEncoding; - try - { - Console.InputEncoding = StreamClientSessionTransport.NoBomUtf8Encoding; - processStarted = process.Start(); - } - finally + if (HasConsole()) { - Console.InputEncoding = originalInputEncoding; + try + { + Console.InputEncoding = StreamClientSessionTransport.NoBomUtf8Encoding; + } + finally + { + Console.InputEncoding = originalInputEncoding; + } } #endif + processStarted = process.Start(); if (!processStarted) { @@ -199,7 +200,13 @@ public async Task ConnectAsync(CancellationToken cancellationToken = throw new IOException("Failed to connect transport.", ex); } } + [DllImport("kernel32.dll")] + private static extern IntPtr GetConsoleWindow(); + private static bool HasConsole() + { + try { return GetConsoleWindow() != IntPtr.Zero; } catch { return false; } + } internal static void DisposeProcess( Process? process, bool processRunning, TimeSpan shutdownTimeout, string endpointName) { From 8b0c55e966c0f744fde5d83a35a757b4cb7ace40 Mon Sep 17 00:00:00 2001 From: xiangb-a Date: Mon, 11 Aug 2025 15:35:09 +0800 Subject: [PATCH 2/2] We should determine if it is a console program, and only set the encoding format for the console program if it is a console program --- src/ModelContextProtocol.Core/Client/StdioClientTransport.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs index c828dfc2..ef2bd5e7 100644 --- a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs +++ b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs @@ -156,7 +156,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken = // up the encoding from Console.InputEncoding. As such, when not targeting .NET Core, // we temporarily change Console.InputEncoding to no-BOM UTF-8 around the Process.Start // call, to ensure it picks up the correct encoding. -#if !NET + Encoding originalInputEncoding = Console.InputEncoding; if (HasConsole()) { @@ -169,7 +169,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken = Console.InputEncoding = originalInputEncoding; } } -#endif + processStarted = process.Start(); if (!processStarted)