using System;
namespace Editor.CodeEditors;
[Title( "Visual Studio" )]
public class VisualStudio : ICodeEditor
{
public void OpenFile( string path, int? line, int? column )
{
var sln = CodeEditor.FindSolutionFromPath( System.IO.Path.GetDirectoryName( path ) );
Launch( $"\"{sln}\" \"{path}\" \"{line ?? 1}\"" ); // TODO: vsopen doesn't do column but it's an easy add
}
public void OpenSolution()
{
Launch( $"\"{CodeEditor.AddonSolutionPath()}\"" );
}
public void OpenAddon( Project addon )
{
OpenSolution();
}
public bool IsInstalled() => !string.IsNullOrEmpty( FindVisualStudio() );
///
/// Uses vsopen to open the file in a currently running instance of Visual Studio.
/// Failing that it will launch it.
///
private static void Launch( string arguments )
{
string exe = $"{Environment.CurrentDirectory}/bin/win64/vsopen.exe";
var args = $"\"{FindVisualStudio()}\" {arguments}";
var startInfo = new System.Diagnostics.ProcessStartInfo
{
CreateNoWindow = true,
Arguments = args,
FileName = exe
};
System.Diagnostics.Process.Start( startInfo );
}
static string VisualStudioPath;
///
/// Uses vswhere (https://github.com/microsoft/vswhere) to find where Visual Studio is installed.
/// This will return the most latest version, as well as one with .NET SDK installed.
///
/// The full installation path of devenv.exe or an empty string.
static string FindVisualStudio()
{
if ( VisualStudioPath != null )
{
return VisualStudioPath;
}
// Always use the same one that's already open
foreach ( var p in System.Diagnostics.Process.GetProcessesByName( "devenv" ) )
{
VisualStudioPath = p.MainModule.FileName;
return VisualStudioPath;
}
// Otherwise use vswhere to find the latest one with .NET installed (prerelease is valid too)
var startInfo = new System.Diagnostics.ProcessStartInfo
{
CreateNoWindow = true,
Arguments = "-latest -prerelease -requires Microsoft.NetCore.Component.SDK -property productPath",
FileName = $"{Environment.CurrentDirectory}/bin/win64/vswhere.exe",
RedirectStandardOutput = true
};
var process = System.Diagnostics.Process.Start( startInfo );
VisualStudioPath = process.StandardOutput.ReadToEnd().Trim();
return VisualStudioPath;
}
}