void ViewTypeDependency(object sender, EventArgs e) { var filePath = VisualStudio.ActiveProjectCsprojFilePath; if (filePath == null) { return; } var graphFilePath = filePath + ".dgml"; var FS = new FileService(); FS.TryDelete(graphFilePath); var arguments = string.Format(@"graph={1} source={0} {0}", filePath, graphFilePath); Process.Start(Configuration.PluginDirectory + "DeepEnds\\DeepEnds.Console.exe", arguments); var count = 0; // wait for process finih while (true) { if (!FS.Exists(graphFilePath)) { Thread.Sleep(300); continue; } var fi = new FileInfo(graphFilePath); if (fi.Length > 0) { DgmlHelper.SetDirectionLeftToRight(graphFilePath); VisualStudio.OpenFile(graphFilePath); return; } Thread.Sleep(300); if (count++ > 50) { MessageBox.Show("EvaluationTimeout"); return; } } }
public void SetDirectionLeftToRight_ShouldAddNodeIfNotExists() { const string filePath = "ViewClassDependency\\SetDirectionLeftToRight\\ShouldAddNodeIfNotExists.xml"; var expected = @"<?xml version=""1.0"" encoding=""utf-8""?> <DirectedGraph xmlns=""http://schemas.microsoft.com/vs/2009/dgml""> <Properties> <Property Id=""GraphDirection"" DataType=""Microsoft.VisualStudio.Diagrams.Layout.LayoutOrientation"" /> <Property Id=""Layout"" DataType=""System.String"" /> </Properties> </DirectedGraph>"; DgmlHelper.SetDirectionLeftToRight(filePath); Assert.AreEqual(expected, File.ReadAllText(filePath)); DgmlHelper.SetDirectionLeftToRight(filePath); Assert.AreEqual(expected, File.ReadAllText(filePath)); }
public void TestSave_StyledDgml() { DirectedGraphNode first = new DirectedGraphNode { Id = "1", Label = "first", Category1 = "category", }; DirectedGraphNode second = new DirectedGraphNode { Id = "2", Label = "second" }; DirectedGraphLink link = new DirectedGraphLink { Source = "1", Target = "2", Label = "connects" }; DirectedGraphStyle style = DgmlHelper.CreateCategoryBackgroundStyle("category", "#FF000000"); DirectedGraph graph = new DirectedGraph { Nodes = new[] { first, second }, Links = new[] { link }, Styles = new[] { style }, }; string actualDgml = graph.ToDgml(); MatchDgml(StyledDgml, actualDgml); }
private static void DumpTypes(ClrHeap heap, ulong obj, string type) { Console.WriteLine($"Dumping CompositionContainer @{obj:X}"); // Check if custom ExportProviders are present ulong providersFieldValue = ClrMdHelper.GetObjectAs <ulong>(heap, obj, FIELD_Providers); if (providersFieldValue != 0) { ulong providerArrayObj = ClrMdHelper.GetObjectAs <ulong>(heap, providersFieldValue, FIELD_List); List <ulong> providerObjs = ClrMdHelper.GetArrayItems(heap.GetObjectType(providerArrayObj), providerArrayObj); if (providerObjs.Count > 0) { Console.WriteLine("WARNING: custom ExportProvider(s) were found:"); } foreach (ulong provider in providerObjs) { ClrType itemType = heap.GetObjectType(provider); Console.WriteLine($"\t{itemType.Name}"); } } var RESULT = new Dictionary <string, ReflectionComposablePart>(); // Check if there exists a PartExportProvider ulong partExportProvider = ClrMdHelper.GetObjectAs <ulong>(heap, obj, FIELD_PartExportProvider); if (partExportProvider != 0) { // Get ComposablePart[] from ComposablePartExportProvider List <ulong> composableParts = ClrMdHelper.GetLastObjectInHierarchyAsArray(heap, partExportProvider, HIERARCHY_PartExportProvider_To_ComposableParts, 0, TYPE_ComposablePart); foreach (var composablePart in composableParts) { string composablePartTypeName = heap.GetObjectType(composablePart).Name; if (composablePartTypeName == TYPE_ReflectionComposablePart) { var rcpDef = ClrMdHelper.GetObjectAs <ulong>(heap, composablePart, FIELD_Definition); var rcp = ProcessReflectionComposablePartDefinition(heap, rcpDef); rcp.IsCreated = true; MergeResults(RESULT, rcp); } else if (composablePartTypeName == TYPE_SingleExportComposablePart) { ulong export = ClrMdHelper.GetObjectAs <ulong>(heap, composablePart, FIELD_Export); ulong exportedValue = ClrMdHelper.GetObjectAs <ulong>(heap, export, FIELD_ExportedValue); string exportedValueTypeName = exportedValue != 0 ? heap.GetObjectType(exportedValue).Name : null; bool isCached = exportedValue != 0 && exportedValueTypeName != typeof(object).FullName; if (!isCached) { ulong realExportedValue = ClrMdHelper.GetLastObjectInHierarchy(heap, export, HIERARCHY_Func_To_ExportedValue, 0); if (realExportedValue != 0) { exportedValueTypeName = heap.GetObjectType(realExportedValue).Name; } } var exportDefinition = ClrMdHelper.GetObjectAs <ulong>(heap, export, FIELD_Definition); string contract = ClrMdHelper.GetObjectAs <string>(heap, exportDefinition, FIELD_ContractName); var metadata = ClrMdHelper.GetLastObjectInHierarchyAsKVPs(heap, exportDefinition, HIERARCHY_ExportDefinition_To_Metadata, 0, TYPE_KVP_String_Object); string typeId = ""; foreach (var entry in metadata) { if (ClrMdHelper.GetStringContents(heap, entry.key) == CONST_ExportTypeIdentity) { typeId = ClrMdHelper.GetStringContents(heap, entry.value); break; } } var rcp = new ReflectionComposablePart(); rcp.TypeName = exportedValueTypeName ?? typeId; rcp.IsCreated = true; rcp.Exports.Add(new ExportDefinition() { ContractName = contract, TypeIdentity = typeId }); MergeResults(RESULT, rcp); } else { Console.WriteLine($"WARNING: Unsupported ComposablePart was found: {composablePartTypeName}"); } } } // Check if there exists a CatalogExportProvider ulong catalogExProvider = ClrMdHelper.GetObjectAs <ulong>(heap, obj, FIELD_CatalogExportProvider); if (catalogExProvider != 0) { ulong catalogFieldValue = ClrMdHelper.GetObjectAs <ulong>(heap, catalogExProvider, FIELD_Catalog); HashSet <ulong> parts = new HashSet <ulong>(); InvokeCatalogHandler(heap, catalogFieldValue, parts); foreach (var part in parts) { var rcp = ProcessReflectionComposablePartDefinition(heap, part); MergeResults(RESULT, rcp); } Console.WriteLine($"{RESULT.Count} parts were found: "); foreach (var part in RESULT.Keys) { Console.WriteLine($"\t{part}"); } Console.WriteLine(); // Get activated auto-created parts var activePartObjs = ClrMdHelper.GetLastObjectInHierarchyAsKVPs(heap, catalogExProvider, HIERARCHY_CatalogExportProvider_To_Activated, 0, TYPE_ComposablePartDefinitionArray2); var activatedPartNames = new HashSet <string>(); foreach (var activePart in activePartObjs) { ulong partCreationInfo = ClrMdHelper.GetObjectAs <ulong>(heap, activePart.key, FIELD_CreationInfo); string partType = InvokePartCreationInfoHandler(heap, partCreationInfo); activatedPartNames.Add(partType); } foreach (var rcp in RESULT) { if (activatedPartNames.Contains(rcp.Key)) { rcp.Value.IsCreated = true; } } DgmlHelper.CreateDgml($"{obj:X}.dgml", RESULT.Select(x => x.Value)); } else { Console.WriteLine("INFO: No CatalogExportProvider was found."); } }
static void Main(string[] args) { var retCode = ArgParser.Parse(args, new string[] { "-h", "-?", "/?" }, new string[] { "-a", "-d", "-pid" }); ValidateArguments(retCode); string switchArg = ArgParser.Switches.FirstOrDefault(); if (switchArg != null) { switch (switchArg) { case "-h": case "-?": case "/?": { PrintSyntaxAndExit(retCode); break; } } } var kvp = ArgParser.SwitchesWithValues.FirstOrDefault(); if (!kvp.Equals(default(KeyValuePair <string, string>))) { switch (kvp.Key) { case "-a": { var assemblies = kvp.Value.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var assembly in assemblies) { ValidateFile(assembly); } var aggrCat = new AggregateCatalog(assemblies.Select(x => new AssemblyCatalog(x))); var RESULT = new List <ReflectionComposablePart>(); using (var container = new CompositionContainer(aggrCat)) { foreach (var part in container.Catalog.Parts) { var rfc = new ReflectionComposablePart(); rfc.TypeName = part.ToString(); foreach (var import in part.ImportDefinitions) { var impDef = new ImportDefinition(); string[] s = ParseImportDefinition(import.ToString()); impDef.ContractName = s[0].Substring(s[0].IndexOf("\t") + 1); impDef.RequiredTypeIdentity = s[1].Substring(s[1].IndexOf("\t") + 1); rfc.Imports.Add(impDef); } foreach (var export in part.ExportDefinitions) { var expDef = new ExportDefinition(); expDef.ContractName = export.ContractName; expDef.TypeIdentity = (string)export.Metadata[CONST_ExportTypeIdentity]; rfc.Exports.Add(expDef); } RESULT.Add(rfc); } } DgmlHelper.CreateDgml($"{Guid.NewGuid().ToString()}.dgml", RESULT); break; } case "-d": { string dumpFile = kvp.Value; ValidateFile(dumpFile); var wrapper = ClrMdHelper.LoadDumpFile(dumpFile); InitAndStartProcessing(wrapper); break; } case "-pid": { if (int.TryParse(kvp.Value, out int pid)) { var wrapper = ClrMdHelper.AttachToLiveProcess(pid); InitAndStartProcessing(wrapper); } else { Console.WriteLine($"ERROR: Invalid process id."); Environment.Exit(1); } break; } } } }