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

时间:2015-09-25 21:54:36

标签: c# visual-studio

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

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

2 个答案:

答案 0 :(得分:4)

此代码与命名空间有关,但您可以轻松地将其转换为从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;
    }
}

答案 1 :(得分:3)

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

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

将此方法添加到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));
}

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

List<Type> types= GetAllTypes();