Windows: prefer WinGet Links uv.exe and preserve existing absolute uv command during config writes
parent
b09a86f5fb
commit
9a9267c128
|
|
@ -270,19 +270,29 @@ namespace UnityMcpBridge.Editor.Helpers
|
|||
string[] candidates;
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty;
|
||||
string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) ?? string.Empty;
|
||||
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty;
|
||||
|
||||
candidates = new[]
|
||||
{
|
||||
// Preferred: WinGet Links shims (stable entrypoints)
|
||||
Path.Combine(localAppData, "Microsoft", "WinGet", "Links", "uv.exe"),
|
||||
Path.Combine(programFiles, "WinGet", "Links", "uv.exe"),
|
||||
|
||||
// Common per-user installs
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python313\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python312\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python311\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python310\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python313\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python312\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python311\Scripts\uv.exe"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python310\Scripts\uv.exe"),
|
||||
Path.Combine(localAppData, @"Programs\Python\Python313\Scripts\uv.exe"),
|
||||
Path.Combine(localAppData, @"Programs\Python\Python312\Scripts\uv.exe"),
|
||||
Path.Combine(localAppData, @"Programs\Python\Python311\Scripts\uv.exe"),
|
||||
Path.Combine(localAppData, @"Programs\Python\Python310\Scripts\uv.exe"),
|
||||
Path.Combine(appData, @"Python\Python313\Scripts\uv.exe"),
|
||||
Path.Combine(appData, @"Python\Python312\Scripts\uv.exe"),
|
||||
Path.Combine(appData, @"Python\Python311\Scripts\uv.exe"),
|
||||
Path.Combine(appData, @"Python\Python310\Scripts\uv.exe"),
|
||||
|
||||
// Program Files style installs (if a native installer was used)
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) ?? string.Empty, @"uv\uv.exe"),
|
||||
Path.Combine(programFiles, @"uv\uv.exe"),
|
||||
|
||||
// Try simple name resolution later via PATH
|
||||
"uv.exe",
|
||||
"uv"
|
||||
|
|
|
|||
|
|
@ -1023,6 +1023,68 @@ namespace UnityMcpBridge.Editor.Windows
|
|||
break;
|
||||
}
|
||||
|
||||
// If config already has a working absolute uv path, avoid rewriting it on refresh
|
||||
try
|
||||
{
|
||||
if (mcpClient?.mcpType != McpTypes.ClaudeCode)
|
||||
{
|
||||
// Inspect existing command for stability (Windows absolute path that exists)
|
||||
string existingCommand = null;
|
||||
if (mcpClient?.mcpType == McpTypes.VSCode)
|
||||
{
|
||||
existingCommand = existingConfig?.servers?.unityMCP?.command?.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
existingCommand = existingConfig?.mcpServers?.unityMCP?.command?.ToString();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(existingCommand))
|
||||
{
|
||||
bool keep = false;
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
// Consider absolute, existing paths as stable; prefer WinGet Links
|
||||
if (Path.IsPathRooted(existingCommand) && File.Exists(existingCommand))
|
||||
{
|
||||
keep = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// On Unix, keep absolute existing path as well
|
||||
if (Path.IsPathRooted(existingCommand) && File.Exists(existingCommand))
|
||||
{
|
||||
keep = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keep)
|
||||
{
|
||||
// Merge without replacing the existing command
|
||||
if (mcpClient?.mcpType == McpTypes.VSCode)
|
||||
{
|
||||
existingConfig.servers.unityMCP.args =
|
||||
JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JToken>(
|
||||
JsonConvert.SerializeObject(unityMCPConfig.args)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingConfig.mcpServers.unityMCP.args =
|
||||
JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JToken>(
|
||||
JsonConvert.SerializeObject(unityMCPConfig.args)
|
||||
);
|
||||
}
|
||||
string mergedKeep = JsonConvert.SerializeObject(existingConfig, jsonSettings);
|
||||
File.WriteAllText(configPath, mergedKeep);
|
||||
return "Configured successfully";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { /* fall back to normal write */ }
|
||||
|
||||
// Write the merged configuration back to file
|
||||
string mergedJson = JsonConvert.SerializeObject(existingConfig, jsonSettings);
|
||||
File.WriteAllText(configPath, mergedJson);
|
||||
|
|
|
|||
Loading…
Reference in New Issue