using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.IO; using System.Linq; using Semmle.Util; namespace Semmle.Extraction.CSharp.Standalone { /// /// Locates .NET Runtimes. /// internal static class Runtime { private static string ExecutingRuntime => RuntimeEnvironment.GetRuntimeDirectory(); /// /// Locates .NET Core Runtimes. /// private static IEnumerable CoreRuntimes { get { var dotnetPath = FileUtils.FindProgramOnPath(Win32.IsWindows() ? "dotnet.exe" : "dotnet"); var dotnetDirs = dotnetPath is not null ? new[] { dotnetPath } : new[] { "/usr/share/dotnet", @"C:\Program Files\dotnet" }; var coreDirs = dotnetDirs.Select(d => Path.Combine(d, "shared", "Microsoft.NETCore.App")); var dir = coreDirs.FirstOrDefault(Directory.Exists); if (dir is not null) { return Directory.EnumerateDirectories(dir).OrderByDescending(Path.GetFileName); } return Enumerable.Empty(); } } /// /// Locates .NET Desktop Runtimes. /// This includes Mono and Microsoft.NET. /// private static IEnumerable DesktopRuntimes { get { var monoPath = FileUtils.FindProgramOnPath(Win32.IsWindows() ? "mono.exe" : "mono"); var monoDirs = monoPath is not null ? new[] { monoPath } : new[] { "/usr/lib/mono", @"C:\Program Files\Mono\lib\mono" }; if (Directory.Exists(@"C:\Windows\Microsoft.NET\Framework64")) { return Directory.EnumerateDirectories(@"C:\Windows\Microsoft.NET\Framework64", "v*") .OrderByDescending(Path.GetFileName); } var dir = monoDirs.FirstOrDefault(Directory.Exists); if (dir is not null) { return Directory.EnumerateDirectories(dir) .Where(d => Char.IsDigit(Path.GetFileName(d)[0])) .OrderByDescending(Path.GetFileName); } return Enumerable.Empty(); } } /// /// Gets the .NET runtime location to use for extraction /// public static string GetRuntime(bool useSelfContained) => useSelfContained ? ExecutingRuntime : Runtimes.First(); private static IEnumerable Runtimes { get { foreach (var r in CoreRuntimes) yield return r; foreach (var r in DesktopRuntimes) yield return r; // A bad choice if it's the self-contained runtime distributed in odasa dist. yield return ExecutingRuntime; } } } }