using System; using System.Linq; using System.Threading.Tasks; using System.IO; using Semmle.Util.Logging; using System.Diagnostics; namespace Semmle.Extraction.CIL.Driver { class Program { static void DisplayHelp() { Console.WriteLine("CIL command line extractor"); Console.WriteLine(); Console.WriteLine("Usage: Semmle.Extraction.CIL.Driver.exe [options] path ..."); Console.WriteLine(" --verbose Turn on verbose output"); Console.WriteLine(" --dotnet Extract the .Net Framework"); Console.WriteLine(" --nocache Overwrite existing trap files"); Console.WriteLine(" --no-pdb Do not extract PDB files"); Console.WriteLine(" path A directory/dll/exe to analyze"); } static void ExtractAssembly(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs) { string trapFile; bool extracted; var sw = new Stopwatch(); sw.Start(); Entities.Assembly.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, out trapFile, out extracted); sw.Stop(); logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed); } static void Main(string[] args) { if (args.Length == 0) { DisplayHelp(); return; } var options = ExtractorOptions.ParseCommandLine(args); var layout = new Layout(); var logger = new ConsoleLogger(options.Verbosity); var actions = options. AssembliesToExtract.Select(asm => asm.filename). Select(filename => () => ExtractAssembly(layout, filename, logger, options.NoCache, options.PDB)). ToArray(); foreach (var missingRef in options.MissingReferences) logger.Log(Severity.Info, " Missing assembly " + missingRef); var sw = new Stopwatch(); sw.Start(); var piOptions = new ParallelOptions { MaxDegreeOfParallelism = options.Threads }; Parallel.Invoke(piOptions, actions); sw.Stop(); logger.Log(Severity.Info, "Extraction completed in {0}", sw.Elapsed); } } }