Skip to content

Commit b954897

Browse files
committed
fix: redirect stdin from NUL when launching the server on Windows (#1279)
The Editor is a console-less GUI process. TerminalLauncher spawned cmd.exe with UseShellExecute=false and CreateNoWindow=true and never redirected stdin, so uvx.exe inherited an invalid stdin handle and died with "The handle is invalid. (os error 6)" before the server could start. Redirect stdin from NUL inside the cmd.exe payload so the child gets a valid handle regardless of whether the Editor has a console. Regression from #1201, shipped in v10.1.0.
1 parent bd72241 commit b954897

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

MCPForUnity/Editor/Services/Server/TerminalLauncher.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ public System.Diagnostics.ProcessStartInfo CreateHeadlessProcessStartInfo(string
4242
}
4343

4444
#if UNITY_EDITOR_WIN
45-
// cmd.exe /c "<command> >> "<log>" 2>&1"
45+
// cmd.exe /c "<command> < NUL >> "<log>" 2>&1"
4646
// The whole payload after /c is wrapped in one outer pair of quotes; cmd strips the
4747
// outermost quotes, so inner quotes around the log path survive for paths with spaces.
48-
string winRedirect = $"{command} >> \"{logFilePath}\" 2>&1";
48+
// stdin is redirected from NUL because the Editor is a console-less GUI process: with
49+
// CreateNoWindow and no console handle, uvx.exe would inherit an invalid stdin and die
50+
// with "The handle is invalid. (os error 6)" before launching the server.
51+
string winRedirect = $"{command} < NUL >> \"{logFilePath}\" 2>&1";
4952
return new System.Diagnostics.ProcessStartInfo
5053
{
5154
FileName = "cmd.exe",

TestProjects/UnityMCPTests/Assets/Tests/EditMode/Services/Server/TerminalLauncherTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,19 @@ public void CreateHeadlessProcessStartInfo_RedirectsOutputToLogFile()
212212
StringAssert.Contains(">>", startInfo.Arguments, "output should be appended to the log via >>");
213213
}
214214

215+
#if UNITY_EDITOR_WIN
216+
[Test]
217+
public void CreateHeadlessProcessStartInfo_RedirectsStdinFromNul()
218+
{
219+
// Regression guard for #1279: the Editor is a console-less GUI process, so a child
220+
// launched with CreateNoWindow inherits an invalid stdin and uvx.exe fails with
221+
// "The handle is invalid. (os error 6)". stdin must come from NUL instead.
222+
var startInfo = _launcher.CreateHeadlessProcessStartInfo("uvx run-server", LogPath());
223+
224+
StringAssert.Contains("< NUL", startInfo.Arguments, "stdin should be redirected from NUL");
225+
}
226+
#endif
227+
215228
[Test]
216229
public void CreateHeadlessProcessStartInfo_LogPathWithSpaces_IsQuoted()
217230
{

0 commit comments

Comments
 (0)