我已成功创建Visual Studio Extension项目。 它工作得很好,整洁。我为解决方案做了一些活动。
MSDN和互联网上的手册很简短。我找不到我的问题的答案: 如何在安装此扩展包的解决方案中检索与类和接口(命名空间,类名,基类型等)相关的所有元数据?
答案 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();