public string RunQuery(string outputFormat, string query, List <string> defines)
        {
            var options = new CompilerParameters();

            options.ReferencedAssemblies.Add(typeof(Enumerable).Assembly.Location);
            options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
            options.ReferencedAssemblies.Add(typeof(ClrHeap).Assembly.Location);
            options.ReferencedAssemblies.Add(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.Location);
            options.CompilerOptions = "/optimize+";

            string compilationOutputDir = Path.Combine(Path.GetTempPath(), "msos_" + Guid.NewGuid().ToString());

            Directory.CreateDirectory(compilationOutputDir);
            options.OutputAssembly = Path.ChangeExtension(
                Path.Combine(compilationOutputDir, CompiledQueryAssemblyName),
                ".dll");

            string source = CompiledQueryTemplate.Replace(CompiledQueryPlaceholder, query);

            source = source.Replace(HelperDefinesPlaceholder,
                                    String.Join(Environment.NewLine + Environment.NewLine, defines.ToArray()));

            var             compiler = new CSharpCodeProvider();
            CompilerResults results  = compiler.CompileAssemblyFromSource(options, source);

            if (results.Errors.HasErrors)
            {
                throw new RunFailedException(
                          String.Format("Query compilation failed with {0} errors:" + Environment.NewLine + "{1}",
                                        results.Errors.Count,
                                        String.Join(Environment.NewLine, (from error in results.Errors.Cast <CompilerError>() select error.ToString()).ToArray())
                                        ));
            }

            Type      compiledQueryType = results.CompiledAssembly.GetType("RunQuery");
            IRunQuery runQuery          = (IRunQuery)Activator.CreateInstance(
                compiledQueryType, new RunQueryContext {
                Heap = _heap, Runtime = _runtime
            });

            object result = runQuery.Run();

            IObjectPrinter printer = null;

            switch ((HeapQueryOutputFormat)Enum.Parse(typeof(HeapQueryOutputFormat), outputFormat))
            {
            case HeapQueryOutputFormat.Tabular:
                printer = new TabularObjectPrinter(_printer);
                break;

            case HeapQueryOutputFormat.Json:
                printer = new JsonObjectPrinter(_printer);
                break;

            default:
                throw new NotSupportedException(String.Format(
                                                    "The output format '{0}' is not supported", outputFormat));
            }

            IEnumerable enumerable = result as IEnumerable;
            ulong       rowCount   = 0;

            if (enumerable != null && !(result is string))
            {
                bool first = true;
                foreach (var obj in enumerable)
                {
                    if (obj is ulong)
                    {
                        _printer.WriteCommandOutput(((ulong)obj).ToString("x16") + Environment.NewLine);
                    }
                    else if (obj.IsAnonymousType())
                    {
                        if (first)
                        {
                            printer.PrintHeader(obj);
                            first = false;
                        }
                        printer.PrintContents(obj);
                    }
                    else
                    {
                        _printer.WriteCommandOutput(obj.ToString() + Environment.NewLine);
                    }
                    ++rowCount;
                }
            }
            else
            {
                _printer.WriteCommandOutput(result.ToString() + Environment.NewLine);
                ++rowCount;
            }
            _printer.WriteCommandOutput("Rows: {0}" + Environment.NewLine, rowCount);

            return(compilationOutputDir);
        }
示例#2
0
 private static ICrud InstantiateCrud()
 {
     crud  = new Crud();
     query = RunQuery.GetInstance;
     return(crud);
 }