Files
sbox-public/game/addons/tools/Code/CodeEditors/CodeEditor.Rider.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

150 lines
4.2 KiB
C#

using System;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Win32;
namespace Editor.CodeEditors;
[Title( "Rider" )]
public class Rider : ICodeEditor
{
public void OpenFile( string path, int? line = null, int? column = null )
{
var solution = CodeEditor.FindSolutionFromPath( System.IO.Path.GetDirectoryName( path ) );
var args = new StringBuilder();
args.Append( $"\"{solution}\" " );
if ( line is not null )
args.Append( $"--line {line} " );
if ( column is not null )
args.Append( $"--column {column} " );
args.Append( $"\"{path}\"" );
Launch( args.ToString() );
}
public void OpenSolution()
{
Launch( $"\"{CodeEditor.AddonSolutionPath()}\"" );
}
public void OpenAddon( Project addon )
{
OpenSolution();
}
public bool IsInstalled() => !string.IsNullOrEmpty( FindRider() );
private static void Launch( string arguments )
{
var startInfo = new System.Diagnostics.ProcessStartInfo
{
CreateNoWindow = true,
Arguments = arguments,
FileName = FindRider()
};
System.Diagnostics.Process.Start( startInfo );
}
private static string RiderPath;
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>" )]
private static string FindRider()
{
if ( RiderPath != null )
{
return RiderPath;
}
// Always use whatever the user has open first as you can have multiple Rider installations
foreach ( var p in System.Diagnostics.Process.GetProcessesByName( "rider64" ) )
{
RiderPath = p.MainModule.FileName;
return RiderPath;
}
string value = null;
using ( var key = Registry.ClassesRoot.OpenSubKey( @"Applications\\rider64.exe\\shell\\open\\command" ) )
{
value = key?.GetValue( "" ) as string;
}
if ( value == null )
{
var riderPathsDict = new Dictionary<string, string>();
using ( var appsSubKey = Registry.ClassesRoot.OpenSubKey( "Applications" ) )
{
var riderKeyNames = appsSubKey?.GetSubKeyNames().Where( name => name.StartsWith( "Toolbox.Rider." ) );
if ( riderKeyNames != null )
{
foreach ( var riderKeyName in riderKeyNames )
{
using var riderKey = appsSubKey.OpenSubKey( riderKeyName + @"\shell\open" );
using var commandKey = riderKey?.OpenSubKey( "command" );
var riderName = riderKey?.GetValue( "FriendlyAppName" ) as string;
var riderPath = commandKey?.GetValue( null ) as string;
if ( riderName != null && riderPath != null )
riderPathsDict.Add( riderName.Split( ' ' ).Skip( 1 ).Aggregate( ( s, s1 ) => s + " " + s1 ), riderPath );
}
}
}
// Convert version to a number so it can be ranked
// Prefers highest major
// Then prefers normal release, Early Access Program version and lastly Nightly
//YYYYMMPPEE
//2024.3.5 - 2024030500
//2024.3.6 - 2024030600
//2024.3 Nigthly - 2024030000
//2025.1 EAP7 - 2025010007
if ( riderPathsDict.Count > 1 )
{
var rankedRiderPathsDict = riderPathsDict.OrderByDescending( pair =>
{
var year = uint.Parse( pair.Key.Split( '.' )[0] );
uint minor;
if ( !pair.Key.Contains( "Nightly" ) && !pair.Key.Contains( "EAP" ) )
minor = uint.Parse( pair.Key.Split( '.' )[1] );
else
minor = uint.Parse( pair.Key.Split( '.' )[1].Split( " " )[0] );
var patch = pair.Key.Contains( "Nightly" ) || pair.Key.Contains( "EAP" )
? 00
: uint.Parse( pair.Key.Split( '.' )[2] );
var eap = pair.Key.Contains( "EAP" )
? uint.Parse( pair.Key.Split( '.' )[1].Split( " " )[1].Replace( "EAP", "" ) )
: 00;
ulong final = year * 1000000 + minor * 10000 + patch * 100 + eap;
return final;
} );
value = rankedRiderPathsDict.First().Value;
}
else
value = riderPathsDict.Count != 0 ? riderPathsDict.First().Value : null;
}
if ( value == null )
{
return null;
}
// Given `"C:\Program Files\JetBrains\JetBrains Rider 2022.1.2\bin\rider64.exe" "%1"` grab the first bit
Regex rgx = new Regex( "\"(.*)\" \".*\"", RegexOptions.IgnoreCase );
var matches = rgx.Matches( value );
if ( matches.Count == 0 || matches[0].Groups.Count < 2 )
{
return null;
}
RiderPath = matches[0].Groups[1].Value;
return RiderPath;
}
}