using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; namespace Semmle.Extraction.CSharp { /// /// Identifies the compiler and framework from the command line arguments. /// --compiler specifies the compiler /// --framework specifies the .net framework /// public class CompilerVersion { const string csc_rsp = "csc.rsp"; readonly string specifiedFramework = null; /// /// The value specified by --compiler, or null. /// public string SpecifiedCompiler { get; private set; } /// /// Why was the candidate exe rejected as a compiler? /// public string SkipReason { get; private set; } /// /// Probes the compiler (if specified). /// /// The command line arguments. public CompilerVersion(Options options) { SpecifiedCompiler = options.CompilerName; specifiedFramework = options.Framework; if (SpecifiedCompiler != null) { if (!File.Exists(SpecifiedCompiler)) { SkipExtractionBecause("the specified file does not exist"); return; } // Reads the file details from the .exe var versionInfo = FileVersionInfo.GetVersionInfo(SpecifiedCompiler); var compilerDir = Path.GetDirectoryName(SpecifiedCompiler); bool known_compiler_name = versionInfo.OriginalFilename == "csc.exe" || versionInfo.OriginalFilename == "csc2.exe"; bool copyright_microsoft = versionInfo.LegalCopyright != null && versionInfo.LegalCopyright.Contains("Microsoft"); bool mscorlib_exists = File.Exists(Path.Combine(compilerDir, "mscorlib.dll")); if (specifiedFramework == null && mscorlib_exists) { specifiedFramework = compilerDir; } if (!known_compiler_name) { SkipExtractionBecause("the exe name is not recognised"); } else if (!copyright_microsoft) { SkipExtractionBecause("the exe isn't copyright Microsoft"); } } } void SkipExtractionBecause(string reason) { SkipExtraction = true; SkipReason = reason; } /// /// The directory containing the .Net Framework. /// public string FrameworkPath => specifiedFramework ?? RuntimeEnvironment.GetRuntimeDirectory(); /// /// The file csc.rsp. /// public string CscRsp => Path.Combine(FrameworkPath, csc_rsp); /// /// Should we skip extraction? /// Only if csc.exe was specified but it wasn't a compiler. /// public bool SkipExtraction { get; private set; } /// /// Gets additional reference directories - the compiler directory. /// public string AdditionalReferenceDirectories => SpecifiedCompiler != null ? Path.GetDirectoryName(SpecifiedCompiler) : null; } }