|
5 | 5 | using System.Runtime.InteropServices; |
6 | 6 | using System.Runtime.Versioning; |
7 | 7 | using System.Text; |
| 8 | +using System.Text.Json; |
8 | 9 |
|
9 | 10 | using Avalonia; |
10 | 11 | using Avalonia.Controls; |
@@ -189,7 +190,7 @@ public string FindTerminal(Models.ShellOrTerminal shell) |
189 | 190 | finder.Fleet(() => Path.Combine(localAppDataDir, @"Programs\Fleet\Fleet.exe")); |
190 | 191 | finder.FindJetBrainsFromToolbox(() => Path.Combine(localAppDataDir, @"JetBrains\Toolbox")); |
191 | 192 | finder.SublimeText(FindSublimeText); |
192 | | - finder.TryAdd("Visual Studio", "vs", FindVisualStudio, GenerateCommandlineArgsForVisualStudio); |
| 193 | + FindVisualStudio(finder); |
193 | 194 | return finder.Tools; |
194 | 195 | } |
195 | 196 |
|
@@ -371,23 +372,41 @@ private string FindSublimeText() |
371 | 372 | return string.Empty; |
372 | 373 | } |
373 | 374 |
|
374 | | - private string FindVisualStudio() |
| 375 | + private void FindVisualStudio(Models.ExternalToolsFinder finder) |
375 | 376 | { |
376 | | - var localMachine = Microsoft.Win32.RegistryKey.OpenBaseKey( |
377 | | - Microsoft.Win32.RegistryHive.LocalMachine, |
378 | | - Microsoft.Win32.RegistryView.Registry64); |
| 377 | + var vswhere = Environment.ExpandEnvironmentVariables(@"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"); |
| 378 | + if (!File.Exists(vswhere)) |
| 379 | + return; |
379 | 380 |
|
380 | | - // Get default class for VisualStudio.Launcher.sln - the handler for *.sln files |
381 | | - if (localMachine.OpenSubKey(@"SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID") is { } launcher) |
| 381 | + var startInfo = new ProcessStartInfo(); |
| 382 | + startInfo.FileName = vswhere; |
| 383 | + startInfo.Arguments = "-format json -prerelease -utf8"; |
| 384 | + startInfo.UseShellExecute = false; |
| 385 | + startInfo.CreateNoWindow = true; |
| 386 | + startInfo.WindowStyle = ProcessWindowStyle.Hidden; |
| 387 | + startInfo.RedirectStandardOutput = true; |
| 388 | + startInfo.StandardOutputEncoding = Encoding.UTF8; |
| 389 | + |
| 390 | + try |
382 | 391 | { |
383 | | - // Get actual path to the executable |
384 | | - if (launcher.GetValue(string.Empty) is string CLSID && |
385 | | - localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is { } devenv && |
386 | | - devenv.GetValue(string.Empty) is string localServer32) |
387 | | - return localServer32!.Trim('\"'); |
388 | | - } |
| 392 | + using var proc = Process.Start(startInfo); |
| 393 | + var output = proc.StandardOutput.ReadToEnd(); |
| 394 | + proc.WaitForExit(); |
389 | 395 |
|
390 | | - return string.Empty; |
| 396 | + if (proc.ExitCode == 0) |
| 397 | + { |
| 398 | + var instances = JsonSerializer.Deserialize(output, JsonCodeGen.Default.ListVisualStudioInstance); |
| 399 | + foreach (var instance in instances) |
| 400 | + { |
| 401 | + var exec = instance.ProductPath; |
| 402 | + finder.TryAdd(instance.DisplayName, "vs", () => exec, GenerateCommandlineArgsForVisualStudio); |
| 403 | + } |
| 404 | + } |
| 405 | + } |
| 406 | + catch |
| 407 | + { |
| 408 | + // Just ignore. |
| 409 | + } |
391 | 410 | } |
392 | 411 |
|
393 | 412 | private string FindCursor() |
|
0 commit comments