fix: Windows define UNITY_EDITOR_WIN; async stdout/stderr in TryRun and RepairPythonEnvironment; use EnvironmentVariables for PATH; prepend Unix PATH only on macOS/Linux; fix duplicate .meta GUIDs
parent
f6f8b24371
commit
efd146ab53
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
|
||||||
|
|
@ -43,7 +44,7 @@ namespace UnityMcpBridge.Editor.Helpers
|
||||||
|
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR_WINDOWS
|
#if UNITY_EDITOR_WIN
|
||||||
// Common npm global locations
|
// Common npm global locations
|
||||||
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty;
|
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty;
|
||||||
string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty;
|
string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty;
|
||||||
|
|
@ -109,16 +110,35 @@ namespace UnityMcpBridge.Editor.Helpers
|
||||||
if (!string.IsNullOrEmpty(extraPathPrepend))
|
if (!string.IsNullOrEmpty(extraPathPrepend))
|
||||||
{
|
{
|
||||||
string currentPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
string currentPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||||
psi.Environment["PATH"] = string.IsNullOrEmpty(currentPath)
|
psi.EnvironmentVariables["PATH"] = string.IsNullOrEmpty(currentPath)
|
||||||
? extraPathPrepend
|
? extraPathPrepend
|
||||||
: (extraPathPrepend + System.IO.Path.PathSeparator + currentPath);
|
: (extraPathPrepend + System.IO.Path.PathSeparator + currentPath);
|
||||||
}
|
}
|
||||||
using var p = Process.Start(psi);
|
|
||||||
if (p == null) return false;
|
using var process = new Process { StartInfo = psi, EnableRaisingEvents = false };
|
||||||
stdout = p.StandardOutput.ReadToEnd();
|
|
||||||
stderr = p.StandardError.ReadToEnd();
|
var so = new StringBuilder();
|
||||||
if (!p.WaitForExit(timeoutMs)) { try { p.Kill(); } catch { } return false; }
|
var se = new StringBuilder();
|
||||||
return p.ExitCode == 0;
|
process.OutputDataReceived += (_, e) => { if (e.Data != null) so.AppendLine(e.Data); };
|
||||||
|
process.ErrorDataReceived += (_, e) => { if (e.Data != null) se.AppendLine(e.Data); };
|
||||||
|
|
||||||
|
if (!process.Start()) return false;
|
||||||
|
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
|
||||||
|
if (!process.WaitForExit(timeoutMs))
|
||||||
|
{
|
||||||
|
try { process.Kill(); } catch { }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure async buffers are flushed
|
||||||
|
process.WaitForExit();
|
||||||
|
|
||||||
|
stdout = so.ToString();
|
||||||
|
stderr = se.ToString();
|
||||||
|
return process.ExitCode == 0;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
@ -138,7 +158,7 @@ namespace UnityMcpBridge.Editor.Helpers
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true,
|
||||||
};
|
};
|
||||||
string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||||
psi.Environment["PATH"] = string.IsNullOrEmpty(path) ? prependPath : (prependPath + Path.PathSeparator + path);
|
psi.EnvironmentVariables["PATH"] = string.IsNullOrEmpty(path) ? prependPath : (prependPath + Path.PathSeparator + path);
|
||||||
using var p = Process.Start(psi);
|
using var p = Process.Start(psi);
|
||||||
string output = p?.StandardOutput.ReadToEnd().Trim();
|
string output = p?.StandardOutput.ReadToEnd().Trim();
|
||||||
p?.WaitForExit(1500);
|
p?.WaitForExit(1500);
|
||||||
|
|
@ -148,7 +168,7 @@ namespace UnityMcpBridge.Editor.Helpers
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UNITY_EDITOR_WINDOWS
|
#if UNITY_EDITOR_WIN
|
||||||
private static string Where(string exe)
|
private static string Where(string exe)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,3 @@ MonoImporter:
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 3f130216be0fd4a57ab7d646a85c6d54
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
@ -206,12 +207,35 @@ namespace UnityMcpBridge.Editor.Helpers
|
||||||
CreateNoWindow = true
|
CreateNoWindow = true
|
||||||
};
|
};
|
||||||
|
|
||||||
using var p = System.Diagnostics.Process.Start(psi);
|
using var proc = new System.Diagnostics.Process { StartInfo = psi };
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
var sbOut = new StringBuilder();
|
||||||
string stderr = p.StandardError.ReadToEnd();
|
var sbErr = new StringBuilder();
|
||||||
p.WaitForExit(60000);
|
proc.OutputDataReceived += (_, e) => { if (e.Data != null) sbOut.AppendLine(e.Data); };
|
||||||
|
proc.ErrorDataReceived += (_, e) => { if (e.Data != null) sbErr.AppendLine(e.Data); };
|
||||||
|
|
||||||
if (p.ExitCode != 0)
|
if (!proc.Start())
|
||||||
|
{
|
||||||
|
Debug.LogError("Failed to start uv process.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc.BeginOutputReadLine();
|
||||||
|
proc.BeginErrorReadLine();
|
||||||
|
|
||||||
|
if (!proc.WaitForExit(60000))
|
||||||
|
{
|
||||||
|
try { proc.Kill(); } catch { }
|
||||||
|
Debug.LogError("uv sync timed out.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure async buffers flushed
|
||||||
|
proc.WaitForExit();
|
||||||
|
|
||||||
|
string stdout = sbOut.ToString();
|
||||||
|
string stderr = sbErr.ToString();
|
||||||
|
|
||||||
|
if (proc.ExitCode != 0)
|
||||||
{
|
{
|
||||||
Debug.LogError($"uv sync failed: {stderr}\n{stdout}");
|
Debug.LogError($"uv sync failed: {stderr}\n{stdout}");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -341,7 +365,7 @@ namespace UnityMcpBridge.Editor.Helpers
|
||||||
"/bin"
|
"/bin"
|
||||||
});
|
});
|
||||||
string currentPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
string currentPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||||
whichPsi.Environment["PATH"] = string.IsNullOrEmpty(currentPath) ? prepend : (prepend + ":" + currentPath);
|
whichPsi.EnvironmentVariables["PATH"] = string.IsNullOrEmpty(currentPath) ? prepend : (prepend + ":" + currentPath);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
using var wp = System.Diagnostics.Process.Start(whichPsi);
|
using var wp = System.Diagnostics.Process.Start(whichPsi);
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,3 @@ MonoImporter:
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 9ac156bc74460420290ab50ed91d3a15
|
|
||||||
|
|
@ -1320,10 +1320,14 @@ namespace UnityMcpBridge.Editor.Windows
|
||||||
string args = $"mcp add UnityMCP -- \"{uvPath}\" run --directory \"{srcDir}\" server.py";
|
string args = $"mcp add UnityMCP -- \"{uvPath}\" run --directory \"{srcDir}\" server.py";
|
||||||
|
|
||||||
string projectDir = Path.GetDirectoryName(Application.dataPath);
|
string projectDir = Path.GetDirectoryName(Application.dataPath);
|
||||||
// Ensure PATH includes common Node/npm locations so claude can spawn node internally if needed
|
// Ensure PATH includes common locations on Unix; on Windows leave PATH as-is
|
||||||
string pathPrepend = Application.platform == RuntimePlatform.OSXEditor
|
string pathPrepend = null;
|
||||||
? "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
|
if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.LinuxEditor)
|
||||||
: "/usr/local/bin:/usr/bin:/bin";
|
{
|
||||||
|
pathPrepend = Application.platform == RuntimePlatform.OSXEditor
|
||||||
|
? "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
|
||||||
|
: "/usr/local/bin:/usr/bin:/bin";
|
||||||
|
}
|
||||||
if (!ExecPath.TryRun(claudePath, args, projectDir, out var stdout, out var stderr, 15000, pathPrepend))
|
if (!ExecPath.TryRun(claudePath, args, projectDir, out var stdout, out var stderr, 15000, pathPrepend))
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.LogError($"UnityMCP: Failed to start Claude CLI.\n{stderr}\n{stdout}");
|
UnityEngine.Debug.LogError($"UnityMCP: Failed to start Claude CLI.\n{stderr}\n{stdout}");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue