[英]Visual Studio Extension get all classes and interfaces metadata
I have successfully created the Visual Studio Extension project. 我已成功创建Visual Studio扩展项目。 It works nice and neat.
它工作得很好,整洁。 I made some event for solutions.
我为解决方案做了一些活动。
The manuals in MSDN and the Internet are brief. MSDN和Internet中的手册很简短。 And I cannot find an answer to my question: How can I retrieve all metadata related to the class and interfaces (namespaces, class names, base types, etc.) in the solution where this Extension Package is installed?
我无法找到我的问题的答案:如何在安装此扩展包的解决方案中检索与类和接口(名称空间,类名,基类型等)相关的所有元数据?
This code is about namespace, but you can easily transform it to take everything from CodeModel: 此代码与命名空间有关,但您可以轻松地将其转换为从CodeModel获取所有内容:
public class Metadata
{
public List<Namespace> ExtractNamespaces()
{
var namespaces = new List<Namespace>();
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<string> GetNamespacesRecursive(CodeElement elem)
{
var namespaces = new List<string>();
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<ProjectItem> GetProjectItemsRecursively(ProjectItems items)
{
var ret = new List<EnvDTE.ProjectItem>();
if (items == null) return ret;
foreach (ProjectItem item in items)
{
ret.Add(item);
ret.AddRange(GetProjectItemsRecursively(item.ProjectItems));
}
return ret;
}
}
You can use ITypeDiscoveryService
to list all available types in project. 您可以使用
ITypeDiscoveryService
列出项目中的所有可用类型。
To do this, you should add Microsoft.VisualStudio.Shell.Design
reference to project. 为此,您应该将
Microsoft.VisualStudio.Shell.Design
引用添加到项目中。 This way you can use DynamicTypeService
to get an instance of ITypeDiscoveryService
. 这样,您可以使用
DynamicTypeService
来获取ITypeDiscoveryService
的实例。
Add this methods to your Package
class: 将此方法添加到
Package
类:
public List<Type> GetAllTypes()
{
var trs = GetTypeDiscoveryService();
var types = trs.GetTypes(typeof(object), true /*excludeGlobalTypes*/);
var result = new List<Type>();
foreach (Type type in types)
{
if (type.IsPublic)
{
if (!result.Contains(type))
result.Add(type);
}
}
return result;
}
private ITypeDiscoveryService GetTypeDiscoveryService()
{
var dte = GetService<EnvDTE.DTE>();
var typeService = GetService<DynamicTypeService>();
var solution = GetService<IVsSolution>();
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<T>()
{
return (T)GetService(typeof(T));
}
Then you can use GetAllTypes
to get all types of active project: 然后,您可以使用
GetAllTypes
获取所有类型的活动项目:
List<Type> types= GetAllTypes();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.