Skip to content

Commit f23a25c

Browse files
committed
Add pwsh cleanup before Named Pipe test to avoid server conflicts
1 parent 6fefa10 commit f23a25c

3 files changed

Lines changed: 40 additions & 25 deletions

File tree

.github/workflows/cross-platform-test.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,21 @@ jobs:
257257
258258
Write-Host "=== Testing Named Pipe Communication ===" -ForegroundColor Cyan
259259
260+
# Clean up any existing pwsh processes that might have Named Pipe servers
261+
Write-Host "Cleaning up existing pwsh processes..."
262+
$currentPid = $PID
263+
$pwshProcs = Get-Process -Name pwsh -ErrorAction SilentlyContinue | Where-Object { $_.Id -ne $currentPid }
264+
if ($pwshProcs) {
265+
Write-Host "Found $($pwshProcs.Count) other pwsh process(es), terminating..."
266+
$pwshProcs | ForEach-Object {
267+
Write-Host " Killing PID $($_.Id)"
268+
$_ | Stop-Process -Force -ErrorAction SilentlyContinue
269+
}
270+
Start-Sleep -Seconds 1
271+
} else {
272+
Write-Host "No other pwsh processes found"
273+
}
274+
260275
# Start a background pwsh process with PowerShell.MCP imported
261276
Write-Host "Starting background pwsh with PowerShell.MCP..."
262277
$bgPsi = [System.Diagnostics.ProcessStartInfo]::new()

PowerShell.MCP.Proxy/Services/NamedPipeClient.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public async Task<string> SendRequestAsync(string arguments)
2727
try
2828
{
2929
Console.Error.WriteLine("[DEBUG] Connecting to Named Pipe (3s timeout)...");
30-
await pipeClient.ConnectAsync(1000 * 3); // 3 second timeout
30+
await pipeClient.ConnectAsync(1000 * 3).ConfigureAwait(false); // 3 second timeout
3131
Console.Error.WriteLine("[DEBUG] Connected to Named Pipe successfully");
3232
}
3333
catch (TimeoutException)
@@ -45,13 +45,13 @@ public async Task<string> SendRequestAsync(string arguments)
4545
Console.Error.WriteLine($"[DEBUG] Sending length prefix: {messageBytes.Length}");
4646

4747
// Send message length prefix + JSON message body
48-
await pipeClient.WriteAsync(lengthBytes, 0, lengthBytes.Length);
49-
await pipeClient.WriteAsync(messageBytes, 0, messageBytes.Length);
50-
await pipeClient.FlushAsync();
48+
await pipeClient.WriteAsync(lengthBytes, 0, lengthBytes.Length).ConfigureAwait(false);
49+
await pipeClient.WriteAsync(messageBytes, 0, messageBytes.Length).ConfigureAwait(false);
50+
await pipeClient.FlushAsync().ConfigureAwait(false);
5151
Console.Error.WriteLine("[DEBUG] Message sent, waiting for response...");
5252

5353
// Receive response: proper length prefix handling
54-
var response = await ReceiveMessageAsync(pipeClient);
54+
var response = await ReceiveMessageAsync(pipeClient).ConfigureAwait(false);
5555
Console.Error.WriteLine($"[DEBUG] Response received, length: {response.Length}");
5656
return response;
5757
}
@@ -74,7 +74,7 @@ private async Task<string> ReceiveMessageAsync(NamedPipeClientStream pipeClient)
7474

7575
// 1. Read message length (4 bytes) reliably
7676
var lengthBuffer = new byte[4];
77-
await ReadExactAsync(pipeClient, lengthBuffer, 4);
77+
await ReadExactAsync(pipeClient, lengthBuffer, 4).ConfigureAwait(false);
7878

7979
var messageLength = BitConverter.ToInt32(lengthBuffer, 0);
8080
Console.Error.WriteLine($"[DEBUG] ReceiveMessageAsync: Message length = {messageLength}");
@@ -88,7 +88,7 @@ private async Task<string> ReceiveMessageAsync(NamedPipeClientStream pipeClient)
8888
// 3. Read message body reliably
8989
Console.Error.WriteLine($"[DEBUG] ReceiveMessageAsync: Reading message body...");
9090
var messageBuffer = new byte[messageLength];
91-
await ReadExactAsync(pipeClient, messageBuffer, messageLength);
91+
await ReadExactAsync(pipeClient, messageBuffer, messageLength).ConfigureAwait(false);
9292

9393
// 4. UTF-8 decode
9494
var result = Encoding.UTF8.GetString(messageBuffer);
@@ -102,7 +102,7 @@ private async Task ReadExactAsync(NamedPipeClientStream pipeClient, byte[] buffe
102102

103103
while (totalBytesRead < count)
104104
{
105-
var bytesRead = await pipeClient.ReadAsync(buffer, totalBytesRead, count - totalBytesRead);
105+
var bytesRead = await pipeClient.ReadAsync(buffer, totalBytesRead, count - totalBytesRead).ConfigureAwait(false);
106106

107107
if (bytesRead == 0)
108108
{
@@ -126,10 +126,10 @@ public static async Task<bool> WaitForPipeReadyAsync()
126126
try
127127
{
128128
using var testClient = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut);
129-
await testClient.ConnectAsync(500); // 500ms timeout
129+
await testClient.ConnectAsync(500).ConfigureAwait(false); // 500ms timeout
130130
Console.Error.WriteLine($"[INFO] Named Pipe ready after {attempt} attempts");
131131
// Give the server time to prepare for the next connection
132-
await Task.Delay(500);
132+
await Task.Delay(500).ConfigureAwait(false);
133133
return true;
134134
}
135135
catch (TimeoutException)

PowerShell.MCP/Services/NamedPipeServer.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ private async Task RunServerInstanceAsync(CancellationToken cancellationToken)
8181
// Wait for client connection
8282
Console.Error.WriteLine("[DEBUG] Before WaitForConnectionAsync");
8383
Console.Error.Flush();
84-
await pipeServer.WaitForConnectionAsync(cancellationToken);
84+
await pipeServer.WaitForConnectionAsync(cancellationToken).ConfigureAwait(false);
8585
Console.Error.WriteLine("[DEBUG] After WaitForConnectionAsync - Client connected to Named Pipe");
8686
Console.Error.Flush();
8787

8888
// Handle communication with connected client
89-
await HandleClientAsync(pipeServer, cancellationToken);
89+
await HandleClientAsync(pipeServer, cancellationToken).ConfigureAwait(false);
9090
}
9191
catch (OperationCanceledException)
9292
{
@@ -103,7 +103,7 @@ private async Task RunServerInstanceAsync(CancellationToken cancellationToken)
103103
// Wait a moment before retrying on error
104104
try
105105
{
106-
await Task.Delay(1000, cancellationToken);
106+
await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
107107
}
108108
catch (OperationCanceledException)
109109
{
@@ -149,7 +149,7 @@ private static async Task HandleClientAsync(NamedPipeServerStream pipeServer, Ca
149149
{
150150
// Receive request
151151
Console.Error.WriteLine("[DEBUG] Calling ReceiveMessageAsync...");
152-
var requestJson = await ReceiveMessageAsync(pipeServer, cancellationToken);
152+
var requestJson = await ReceiveMessageAsync(pipeServer, cancellationToken).ConfigureAwait(false);
153153
Console.Error.WriteLine($"[DEBUG] Received request: {requestJson.Substring(0, Math.Min(100, requestJson.Length))}...");
154154

155155
// Parse JSON-RPC request
@@ -180,7 +180,7 @@ private static async Task HandleClientAsync(NamedPipeServerStream pipeServer, Ca
180180
181181
Please provide how to update the MCP client configuration to the user.";
182182

183-
await SendMessageAsync(pipeServer, versionErrorResponse, cancellationToken);
183+
await SendMessageAsync(pipeServer, versionErrorResponse, cancellationToken).ConfigureAwait(false);
184184
return;
185185
}
186186

@@ -194,15 +194,15 @@ 2. Manually terminate console (LLM will then restart automatically)
194194
195195
LLM should prompt user to choose.";
196196

197-
await SendMessageAsync(pipeServer, busyResponse, cancellationToken);
197+
await SendMessageAsync(pipeServer, busyResponse, cancellationToken).ConfigureAwait(false);
198198
return;
199199
}
200200

201201
// Execute tool
202-
var result = await Task.Run(() => ExecuteTool(name!, requestRoot));
202+
var result = await Task.Run(() => ExecuteTool(name!, requestRoot)).ConfigureAwait(false);
203203

204204
// Send response
205-
await SendMessageAsync(pipeServer, result, cancellationToken);
205+
await SendMessageAsync(pipeServer, result, cancellationToken).ConfigureAwait(false);
206206
}
207207
catch (Exception ex)
208208
{
@@ -226,7 +226,7 @@ 2. Manually terminate console (LLM will then restart automatically)
226226

227227
try
228228
{
229-
await SendMessageAsync(pipeServer, errorJson, cancellationToken);
229+
await SendMessageAsync(pipeServer, errorJson, cancellationToken).ConfigureAwait(false);
230230
}
231231
catch
232232
{
@@ -270,7 +270,7 @@ private static async Task<string> ReceiveMessageAsync(NamedPipeServerStream pipe
270270

271271
// Receive message length (4 bytes)
272272
var lengthBytes = new byte[4];
273-
await ReadExactAsync(pipeServer, lengthBytes, cancellationToken);
273+
await ReadExactAsync(pipeServer, lengthBytes, cancellationToken).ConfigureAwait(false);
274274
var messageLength = BitConverter.ToInt32(lengthBytes, 0);
275275
Console.Error.WriteLine($"[DEBUG] Server ReceiveMessageAsync: Message length = {messageLength}");
276276

@@ -282,7 +282,7 @@ private static async Task<string> ReceiveMessageAsync(NamedPipeServerStream pipe
282282
// Receive message body
283283
Console.Error.WriteLine("[DEBUG] Server ReceiveMessageAsync: Reading message body...");
284284
var messageBytes = new byte[messageLength];
285-
await ReadExactAsync(pipeServer, messageBytes, cancellationToken);
285+
await ReadExactAsync(pipeServer, messageBytes, cancellationToken).ConfigureAwait(false);
286286
Console.Error.WriteLine("[DEBUG] Server ReceiveMessageAsync: Complete");
287287

288288
return Encoding.UTF8.GetString(messageBytes);
@@ -297,11 +297,11 @@ public static async Task SendMessageAsync(NamedPipeServerStream pipeServer, stri
297297
var lengthBytes = BitConverter.GetBytes(messageBytes.Length);
298298

299299
// Send message length (4 bytes)
300-
await pipeServer.WriteAsync(lengthBytes, 0, 4, cancellationToken);
300+
await pipeServer.WriteAsync(lengthBytes, 0, 4, cancellationToken).ConfigureAwait(false);
301301

302302
// Send message body
303-
await pipeServer.WriteAsync(messageBytes, 0, messageBytes.Length, cancellationToken);
304-
await pipeServer.FlushAsync(cancellationToken);
303+
await pipeServer.WriteAsync(messageBytes, 0, messageBytes.Length, cancellationToken).ConfigureAwait(false);
304+
await pipeServer.FlushAsync(cancellationToken).ConfigureAwait(false);
305305
}
306306

307307
/// <summary>
@@ -312,7 +312,7 @@ private static async Task ReadExactAsync(NamedPipeServerStream stream, byte[] bu
312312
var totalBytesRead = 0;
313313
while (totalBytesRead < buffer.Length)
314314
{
315-
var bytesRead = await stream.ReadAsync(buffer, totalBytesRead, buffer.Length - totalBytesRead, cancellationToken);
315+
var bytesRead = await stream.ReadAsync(buffer, totalBytesRead, buffer.Length - totalBytesRead, cancellationToken).ConfigureAwait(false);
316316
if (bytesRead == 0)
317317
{
318318
throw new IOException("Connection closed while reading data");

0 commit comments

Comments
 (0)