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;
|
string[] candidates;
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
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[]
|
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
|
// Common per-user installs
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python313\Scripts\uv.exe"),
|
Path.Combine(localAppData, @"Programs\Python\Python313\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python312\Scripts\uv.exe"),
|
Path.Combine(localAppData, @"Programs\Python\Python312\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python311\Scripts\uv.exe"),
|
Path.Combine(localAppData, @"Programs\Python\Python311\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) ?? string.Empty, @"Programs\Python\Python310\Scripts\uv.exe"),
|
Path.Combine(localAppData, @"Programs\Python\Python310\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python313\Scripts\uv.exe"),
|
Path.Combine(appData, @"Python\Python313\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python312\Scripts\uv.exe"),
|
Path.Combine(appData, @"Python\Python312\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python311\Scripts\uv.exe"),
|
Path.Combine(appData, @"Python\Python311\Scripts\uv.exe"),
|
||||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ?? string.Empty, @"Python\Python310\Scripts\uv.exe"),
|
Path.Combine(appData, @"Python\Python310\Scripts\uv.exe"),
|
||||||
|
|
||||||
// Program Files style installs (if a native installer was used)
|
// 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
|
// Try simple name resolution later via PATH
|
||||||
"uv.exe",
|
"uv.exe",
|
||||||
"uv"
|
"uv"
|
||||||
|
|
|
||||||
|
|
@ -1023,6 +1023,68 @@ namespace UnityMcpBridge.Editor.Windows
|
||||||
break;
|
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
|
// Write the merged configuration back to file
|
||||||
string mergedJson = JsonConvert.SerializeObject(existingConfig, jsonSettings);
|
string mergedJson = JsonConvert.SerializeObject(existingConfig, jsonSettings);
|
||||||
File.WriteAllText(configPath, mergedJson);
|
File.WriteAllText(configPath, mergedJson);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue