简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM