使用DXCore控制台应用程序获取解决方案/项目中的文件列表

5
我了解以下代码片段可以在插件中使用来提取VS解决方案信息。
EnvDTE.Solution solution = CodeRush.ApplicationObject.Solution;
EnvDTE.Projects projects = solution.Projects;

问:我想建立一个控制台应用程序并访问这些文件的详细信息。我的目标是创建一个控制台应用程序(可以在没有VS的情况下运行),根据输入.sln文件中发现的设计问题生成报告。我应该使用哪些函数来实现这一目标?


1
我想要以控制台应用程序的形式提供解决方案的位置,并访问它的所有项目文件,而不是作为插件(类库)。 - Shaun
1
这是一个相当复杂的任务,因为DXCore并不是设计用于在Visual Studio环境之外使用。 - Alex Skorkin
谢谢Alex。但我也可以在控制台应用程序中使用大多数函数。我能够按顺序解析多个文件,但我想输入一个解决方案文件,然后处理其中的所有文件。 你能给个想法这个任务有多复杂吗??谢谢 - Shaun
2
在IDE之外,DXCore可以解析文件(或整个解决方案),因此您可以枚举解决方案元素、获取它们的特性(例如代码度量),并生成代码。但是,您无法使用DXCore API更改文件,并且没有DXCore服务可用(通过CodeRush.XXX方法访问)。另一方面,DXCore服务可以被模拟,但需要完全重写它们。我将在我的网站上创建一篇博客文章,介绍如何在Visual Studio之外使用DXCore。这将需要编写大量代码,如果一切顺利,我也将分享这些代码。 - Alex Skorkin
@Shaun,变更非常巨大,这是最大规模的部分。有太多需要手动完成的事情,例如:阅读每个项目的设置,如语言、文件列表、程序集引用列表等。 - Alex Skorkin
显示剩余2条评论
1个回答

9

原始(更新后的)帖子位于此处

实际上,DXCore 不是设计用于在 Visual Studio 之外使用的,但总有解决方法…… 在本文中,我将向您展示如何在常规 C# 控制台应用程序中使用 DXCore Framework 解析整个解决方案并使用抽象解析树进行操作。解决方案应作为完整路径传递给程序作为参数传入 *.sln 文件。如果未使用参数,则使用测试程序的硬编码路径,因此程序将解析自身并打印有关解决方案的信息,例如所有使用的类型列表以及每个类内的成员数量。

让我们创建一个新的 C# 控制台应用程序,命名为 TestDXCoreConsoleApp 并将其保存在“C:\Project”文件夹中:

Creating a new Console App

接下来,我们需要将新项目的目标框架版本更改为Framework 4.0,而不是"目标框架4.0客户端配置文件",因为一些必需的程序集引用不支持此目标框架版本:

Settings Target Framework

现在,让我们添加必需的程序集引用。以下是我们需要的列表:
  1. DXCore程序集:
  • DevExpress.CodeRush.Common
  • DevExpress.CodeRush.Core
  • DevExpress.CodeRush.StructuralParser
  • DevExpress.CodeRush.VSCore
  • DevExpress.DXCore.AssemblyResolver
  • DevExpress.DXCore.Parser

这些程序集可以在您的DevExpress IDE工具安装文件夹中找到。例如,路径可能如下:

C:\Program Files\DevExpress 2011.1\IDETools\System\DXCore\BIN

  1. 现在,为了支持不同的编程语言,我们需要另外三个程序集:
  • DX_CPPLanguage
  • DX_CSharpLanguage
  • DX_VBLanguage

有了这些程序集,我们就能够解析CSharp、Visual Basic和C++项目。它们可以在以下位置找到:

C:\Program Files (x86)\DevExpress 2011.1\IDETools\System\DXCore\BIN\SYSTEM

  1. .NET Framework程序集:
  • Microsoft.Build.BuildEngine.dll
And, finally, a couple of Visual Studio assemblies:
  • EnvDTE
  • VsLangProj
These two can be found in the "PublicAssemblies" folder:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\

Now, the DXCore support code. This code is required to load a solution, its projects and initialize DXCore parsers. I've added two folders:
The Helpers folder contains the following classes:
  • LanguageHelper.cs - detects the language of projects (e.g. CSharp, Visual Basic or C++).
  • ParserHelper.cs - initializes DXCore parsers, and a few important DXCore services - the Source Model service and the Language service which are used to parse source code.
  • SolutionParser.cs - a helper class, which takes the path to the solution that you are going to parse. Calling the GetParsedSolution method will return the SolutionElement, which holds the abstract source tree of the entire solution.
2. Loaders文件夹包含不同版本Visual Studio的项目和解决方案加载器。它们用于解析*.XXproj和*.sln文件。有VS2002、VS2003和VS2005的版本。没有专门为VS2008和VS2010提供的加载器,因为这些旧版VS的加载器完全可以读取和加载更新的Visual Studio项目和解决方案格式文件(例如2008、2010)。
以下是TestDXCoreConsoleApp的最终结构:

DXCore ConsoleApp structure

完整源代码的TestDXCoreConsoleApp在这里(267,457字节,C#,VS2010)可以查看,您可以审查代码并根据需要使用它。以下是Program类的Main函数:

static void Main(string[] args)
{
  string SolutionPath;
  if (args != null && args.Length > 0)
    SolutionPath = args[0];
  else
    SolutionPath = @"c:\Projects\TestDXCoreConsoleApp\TestDXCoreConsoleApp.sln";

  try
  {
    ParserHelper.RegisterParserServices();

    Console.Write("Parsing solution... ");

    SolutionParser solutionParser = new SolutionParser(SolutionPath);
    SolutionElement solution = solutionParser.GetParsedSolution();
    if (solution == null)
      return;

    Console.WriteLine("Done.");

    foreach (ProjectElement project in solution.AllProjects)
      foreach (SourceFile file in project.AllFiles)
        foreach (TypeDeclaration type in file.AllTypes)
        {
          Console.Write(type.FullName);
          Console.WriteLine(", members: " + ((ITypeElement)type).Members.Count);
        }
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex.Message);
  }
  finally
  {
    ParserHelper.UnRegisterParserServices();
  }

  Console.ReadLine();
}

如果您将源代码放入“C:\Projects”文件夹中,并在不指定任何参数的情况下运行程序,则应该看到以下结果:

DXCore Console App result

按下回车键关闭窗口。请注意,解析过程可能需要一些时间,因此您可能需要等待几秒钟,直到整个解决方案被解析。


@Alex:非常感谢您的精彩博客。我试图在main()程序中使用classInstance.GetBaseTypes();,但这并没有起作用。 异常:ParserServices.ProfilingService:在调用之前必须注册ProfilingService。 谢谢。 - Vinod Menezes
@Shaun,示例程序没有使用字典来存储任何键/值。看起来在DXCore框架内部存在一些问题。如果您能提供调用堆栈或一个可复制的项目,我们将尝试修复问题。 - Alex Skorkin
1
@Vinod,为了修复ParserServices.ProfilingService的异常,请打开ParserHelper.cs并将以下代码行放入RegisterParserServices()方法中:IProfilingService lProfiling = (IProfilingService)CreateParserService(typeof(ProfilingServices)); ParserServices.RegisterProfilingService(lProfiling);别忘了将以下代码行放入UnRegisterParserServices()方法中:ParserServices.UnregisterProfilingService(); - Alex Skorkin
@Alex:以下输出是从 System.Environment.StackTrace() 获得的: 在 System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) 中 在 System.Environment.get_StackTrace() 中 在 F:\Internship\implementation\Code plugins\TestDXCoreConsoleApp\solnProgram.cs 的第 77 行中,TestDXCoreConsoleApp.Program.Main(String[] args) 在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 中 在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 中 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 中 - Shaun
在System.Threading.ThreadHelper.ThreadStart_Context(Object state)处 在System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)处 在System.Threading.ThreadHelper.ThreadStart()处 - Shaun
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接