Visual Studio Extension获取所有类和接口元数据

我已成功创建Visual Studio扩展项目。 它工作得很好,很整洁。 我为解决方案做了一些活动。

MSDN和Internet中的手册很简短。 我无法找到我的问题的答案:如何在安装此扩展包的解决方案中检索与类和接口(名称空间,类名,基类型等)相关的所有元数据?

您可以使用ITypeDiscoveryService列出项目中的所有可用类型。

为此,您应该将Microsoft.VisualStudio.Shell.Design引用添加到项目中。 这样,您可以使用DynamicTypeService来获取ITypeDiscoveryService的实例。

将此方法添加到Package类:

 public List GetAllTypes() { var trs = GetTypeDiscoveryService(); var types = trs.GetTypes(typeof(object), true /*excludeGlobalTypes*/); var result = new List(); foreach (Type type in types) { if (type.IsPublic) { if (!result.Contains(type)) result.Add(type); } } return result; } private ITypeDiscoveryService GetTypeDiscoveryService() { var dte = GetService(); var typeService = GetService(); var solution = GetService(); IVsHierarchy hier; var projects = dte.ActiveSolutionProjects as Array; var currentProject = projects.GetValue(0) as Project; solution.GetProjectOfUniqueName(currentProject.UniqueName, out hier); return typeService.GetTypeDiscoveryService(hier); } private T GetService() { return (T)GetService(typeof(T)); } 

然后,您可以使用GetAllTypes来获取所有类型的活动项目:

 List types= GetAllTypes(); 

此代码与命名空间有关,但您可以轻松地将其转换为从CodeModel获取所有内容:

 public class Metadata { public List ExtractNamespaces() { var namespaces = new List(); var service = (DTE)Package.GetGlobalService(typeof(SDTE)); var projects = service.Solution.Projects; foreach (Project project in projects) { var projectItems = GetProjectItemsRecursively(project.ProjectItems); foreach (ProjectItem item in projectItems.Where(i => i.FileCodeModel != null)) { foreach (CodeElement elem in item.FileCodeModel.CodeElements) { namespaces.AddRange(GetNamespacesRecursive(elem).Select(n=>new Namespace(n))); } } } return namespaces.Distinct().OrderBy(n=>n.ToString()).ToList(); } private static List GetNamespacesRecursive(CodeElement elem) { var namespaces = new List(); if (IsNamespaceable(elem.Kind) && IsEmptyNamespace(elem)) { namespaces.Add(string.Empty); } if (elem.Kind == vsCMElement.vsCMElementNamespace && !namespaces.Contains(elem.FullName)) { namespaces.Add(elem.FullName); if (elem.Children != null) { foreach (CodeElement codeElement in elem.Children) { var ns = GetNamespacesRecursive(codeElement); if (ns.Count > 0) namespaces.AddRange(ns); } } } return namespaces; } private static bool IsEmptyNamespace(CodeElement elem) { return elem.FullName.IndexOf('.') < 0; } private static bool IsNamespaceable(vsCMElement kind) { return (kind == vsCMElement.vsCMElementClass || kind == vsCMElement.vsCMElementEnum || kind == vsCMElement.vsCMElementInterface || kind == vsCMElement.vsCMElementStruct); } private static List GetProjectItemsRecursively(ProjectItems items) { var ret = new List(); if (items == null) return ret; foreach (ProjectItem item in items) { ret.Add(item); ret.AddRange(GetProjectItemsRecursively(item.ProjectItems)); } return ret; } }