mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
C#: Improve logic for looking up .NET runtime in standalone mode
Instead of only considering a fixed set of paths for `dotnet` and `mono`, first attempt to lookup the paths based on the `PATH` environment variable. This change also fixes a potential `System.IO.DirectoryNotFoundException` exception, which could be thrown when the `shared/Microsoft.NETCore.App` folder was not present.
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
@@ -20,11 +21,14 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
get
|
||||
{
|
||||
string[] dotnetDirs = { "/usr/share/dotnet", @"C:\Program Files\dotnet" };
|
||||
var dotnetPath = FileUtils.FindExecutableOnPath("dotnet");
|
||||
var dotnetDirs = dotnetPath != null
|
||||
? new[] { dotnetPath }
|
||||
: new[] { "/usr/share/dotnet", @"C:\Program Files\dotnet" };
|
||||
var coreDirs = dotnetDirs.Select(d => Path.Combine(d, "shared", "Microsoft.NETCore.App"));
|
||||
|
||||
foreach (var dir in dotnetDirs.Where(Directory.Exists))
|
||||
return Directory.EnumerateDirectories(Path.Combine(dir, "shared", "Microsoft.NETCore.App")).
|
||||
OrderByDescending(d => Path.GetFileName(d));
|
||||
foreach (var dir in coreDirs.Where(Directory.Exists))
|
||||
return Directory.EnumerateDirectories(dir).OrderByDescending(Path.GetFileName);
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
}
|
||||
@@ -37,19 +41,22 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
get
|
||||
{
|
||||
string[] monoDirs = { "/usr/lib/mono", @"C:\Program Files\Mono\lib\mono" };
|
||||
var monoPath = FileUtils.FindExecutableOnPath("mono");
|
||||
var monoDirs = monoPath != null
|
||||
? new[] { monoPath }
|
||||
: new[] { "/usr/lib/mono", @"C:\Program Files\Mono\lib\mono" };
|
||||
|
||||
if (Directory.Exists(@"C:\Windows\Microsoft.NET\Framework64"))
|
||||
{
|
||||
return System.IO.Directory.EnumerateDirectories(@"C:\Windows\Microsoft.NET\Framework64", "v*").
|
||||
OrderByDescending(d => Path.GetFileName(d));
|
||||
return Directory.EnumerateDirectories(@"C:\Windows\Microsoft.NET\Framework64", "v*").
|
||||
OrderByDescending(Path.GetFileName);
|
||||
}
|
||||
|
||||
foreach (var dir in monoDirs.Where(Directory.Exists))
|
||||
{
|
||||
return System.IO.Directory.EnumerateDirectories(dir).
|
||||
return Directory.EnumerateDirectories(dir).
|
||||
Where(d => Char.IsDigit(Path.GetFileName(d)[0])).
|
||||
OrderByDescending(d => Path.GetFileName(d));
|
||||
OrderByDescending(Path.GetFileName);
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Util
|
||||
{
|
||||
@@ -50,5 +52,23 @@ namespace Semmle.Util
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the path for the executable <paramref name="exe"/> based on the
|
||||
/// <code>PATH</code> environment variable, and in the case of Windows the
|
||||
/// <code>PATHEXT</code> environment variable.
|
||||
///
|
||||
/// Returns <code>null</code> of no path can be found.
|
||||
/// </summary>
|
||||
public static string FindExecutableOnPath(string exe)
|
||||
{
|
||||
var isWindows = Win32.IsWindows();
|
||||
var paths = Environment.GetEnvironmentVariable("PATH").Split(isWindows ? ';' : ':');
|
||||
var exes = isWindows
|
||||
? Environment.GetEnvironmentVariable("PATHEXT").Split(';').Select(ext => exe + ext)
|
||||
: new[] { exe };
|
||||
var candidates = paths.Where(path => exes.Any(exe0 => File.Exists(Path.Combine(path, exe0))));
|
||||
return candidates.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user