@@ -281,7 +281,7 @@ public static bool RepairPythonEnvironment()
281281 return false ;
282282 }
283283
284- Debug . Log ( "Unity MCP: Python environment repaired successfully." ) ;
284+ Debug . Log ( "<b><color=#2EA3FF>UNITY- MCP</color></b> : Python environment repaired successfully." ) ;
285285 return true ;
286286 }
287287 catch ( Exception ex )
@@ -305,47 +305,100 @@ private static string FindUvPath()
305305 catch { }
306306
307307 string home = Environment . GetFolderPath ( Environment . SpecialFolder . UserProfile ) ?? string . Empty ;
308- string [ ] candidates =
308+
309+ // Platform-specific candidate lists
310+ string [ ] candidates ;
311+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
312+ {
313+ candidates = new [ ]
314+ {
315+ // Common per-user installs
316+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ?? string . Empty , @"Programs\Python\Python313\Scripts\uv.exe" ) ,
317+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ?? string . Empty , @"Programs\Python\Python312\Scripts\uv.exe" ) ,
318+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ?? string . Empty , @"Programs\Python\Python311\Scripts\uv.exe" ) ,
319+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ?? string . Empty , @"Programs\Python\Python310\Scripts\uv.exe" ) ,
320+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) ?? string . Empty , @"Python\Python313\Scripts\uv.exe" ) ,
321+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) ?? string . Empty , @"Python\Python312\Scripts\uv.exe" ) ,
322+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) ?? string . Empty , @"Python\Python311\Scripts\uv.exe" ) ,
323+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) ?? string . Empty , @"Python\Python310\Scripts\uv.exe" ) ,
324+ // Program Files style installs (if a native installer was used)
325+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFiles ) ?? string . Empty , @"uv\uv.exe" ) ,
326+ // Try simple name resolution later via PATH
327+ "uv.exe" ,
328+ "uv"
329+ } ;
330+ }
331+ else
309332 {
310- "/opt/homebrew/bin/uv" ,
311- "/usr/local/bin/uv" ,
312- "/usr/bin/uv" ,
313- "/opt/local/bin/uv" ,
314- Path . Combine ( home , ".local" , "bin" , "uv" ) ,
315- "/opt/homebrew/opt/uv/bin/uv" ,
316- // Framework Python installs
317- "/Library/Frameworks/Python.framework/Versions/3.13/bin/uv" ,
318- "/Library/Frameworks/Python.framework/Versions/3.12/bin/uv" ,
319- // Fallback to PATH resolution by name
320- "uv"
321- } ;
333+ candidates = new [ ]
334+ {
335+ "/opt/homebrew/bin/uv" ,
336+ "/usr/local/bin/uv" ,
337+ "/usr/bin/uv" ,
338+ "/opt/local/bin/uv" ,
339+ Path . Combine ( home , ".local" , "bin" , "uv" ) ,
340+ "/opt/homebrew/opt/uv/bin/uv" ,
341+ // Framework Python installs
342+ "/Library/Frameworks/Python.framework/Versions/3.13/bin/uv" ,
343+ "/Library/Frameworks/Python.framework/Versions/3.12/bin/uv" ,
344+ // Fallback to PATH resolution by name
345+ "uv"
346+ } ;
347+ }
348+
322349 foreach ( string c in candidates )
323350 {
324351 try
325352 {
326- if ( ValidateUvBinary ( c ) ) return c ;
353+ if ( File . Exists ( c ) && ValidateUvBinary ( c ) ) return c ;
327354 }
328355 catch { /* ignore */ }
329356 }
330357
331- // Try which uv (explicit path)
358+ // Use platform-appropriate which/where to resolve from PATH
332359 try
333360 {
334- var whichPsi = new System . Diagnostics . ProcessStartInfo
361+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
335362 {
336- FileName = "/usr/bin/which" ,
337- Arguments = "uv" ,
338- UseShellExecute = false ,
339- RedirectStandardOutput = true ,
340- RedirectStandardError = true ,
341- CreateNoWindow = true
342- } ;
343- using var wp = System . Diagnostics . Process . Start ( whichPsi ) ;
344- string output = wp . StandardOutput . ReadToEnd ( ) . Trim ( ) ;
345- wp . WaitForExit ( 3000 ) ;
346- if ( wp . ExitCode == 0 && ! string . IsNullOrEmpty ( output ) && File . Exists ( output ) )
363+ var wherePsi = new System . Diagnostics . ProcessStartInfo
364+ {
365+ FileName = "where" ,
366+ Arguments = "uv.exe" ,
367+ UseShellExecute = false ,
368+ RedirectStandardOutput = true ,
369+ RedirectStandardError = true ,
370+ CreateNoWindow = true
371+ } ;
372+ using var wp = System . Diagnostics . Process . Start ( wherePsi ) ;
373+ string output = wp . StandardOutput . ReadToEnd ( ) . Trim ( ) ;
374+ wp . WaitForExit ( 3000 ) ;
375+ if ( wp . ExitCode == 0 && ! string . IsNullOrEmpty ( output ) )
376+ {
377+ foreach ( var line in output . Split ( new [ ] { '\r ' , '\n ' } , StringSplitOptions . RemoveEmptyEntries ) )
378+ {
379+ string path = line . Trim ( ) ;
380+ if ( File . Exists ( path ) && ValidateUvBinary ( path ) ) return path ;
381+ }
382+ }
383+ }
384+ else
347385 {
348- if ( ValidateUvBinary ( output ) ) return output ;
386+ var whichPsi = new System . Diagnostics . ProcessStartInfo
387+ {
388+ FileName = "/usr/bin/which" ,
389+ Arguments = "uv" ,
390+ UseShellExecute = false ,
391+ RedirectStandardOutput = true ,
392+ RedirectStandardError = true ,
393+ CreateNoWindow = true
394+ } ;
395+ using var wp = System . Diagnostics . Process . Start ( whichPsi ) ;
396+ string output = wp . StandardOutput . ReadToEnd ( ) . Trim ( ) ;
397+ wp . WaitForExit ( 3000 ) ;
398+ if ( wp . ExitCode == 0 && ! string . IsNullOrEmpty ( output ) && File . Exists ( output ) )
399+ {
400+ if ( ValidateUvBinary ( output ) ) return output ;
401+ }
349402 }
350403 }
351404 catch { }
@@ -359,8 +412,11 @@ private static string FindUvPath()
359412 {
360413 try
361414 {
362- string candidate = Path . Combine ( part , "uv" ) ;
363- if ( File . Exists ( candidate ) && ValidateUvBinary ( candidate ) ) return candidate ;
415+ // Check both uv and uv.exe
416+ string candidateUv = Path . Combine ( part , "uv" ) ;
417+ string candidateUvExe = Path . Combine ( part , "uv.exe" ) ;
418+ if ( File . Exists ( candidateUv ) && ValidateUvBinary ( candidateUv ) ) return candidateUv ;
419+ if ( File . Exists ( candidateUvExe ) && ValidateUvBinary ( candidateUvExe ) ) return candidateUvExe ;
364420 }
365421 catch { }
366422 }
0 commit comments