Visual Studio宏:查找未包含在项目中的文件?

时间:2010-01-04 15:27:00

标签: visual-studio macros visual-studio-macros

我想编写一个宏来抓取项目目录中的文件,并查找未包含在项目中的文件。

在玩DTE对象时,我发现Project对象有ProjectItems;如果ProjectItem表示目录,则它具有自己的ProjectItems集合。这为我提供了项目中包含的所有文件。

因此,我可以递归遍历每个ProjectItems集合,并且对于作为目录的每个ProjectItem,检查文件系统中是否存在没有相应ProjectItem的文件。但这看起来很笨拙。

有任何简单方法可以解决这个问题吗?

4 个答案:

答案 0 :(得分:11)

以下是您的代码的C#版本:

public static void IncludeNewFiles()
{
    int count = 0;
    EnvDTE80.DTE2 dte2;
    List<string> newfiles;

    dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.10.0");

    foreach (Project project in dte2.Solution.Projects)
    {
        if (project.UniqueName.EndsWith(".csproj"))
        {
            newfiles = GetFilesNotInProject(project);

            foreach (var file in newfiles)
                project.ProjectItems.AddFromFile(file);

            count += newfiles.Count;
        }
    }
    dte2.StatusBar.Text = String.Format("{0} new file{1} included in the project.", count, (count == 1 ? "" : "s"));
}

public static List<string> GetAllProjectFiles(ProjectItems projectItems, string extension)
{
    List<string> returnValue = new List<string>();

    foreach(ProjectItem projectItem in projectItems)
    {
        for (short i = 1; i <= projectItems.Count; i++)
        {
            string fileName = projectItem.FileNames[i];
            if (Path.GetExtension(fileName).ToLower() == extension)
                returnValue.Add(fileName);
        }
        returnValue.AddRange(GetAllProjectFiles(projectItem.ProjectItems, extension));        
    }

    return returnValue;
}

public static List<string> GetFilesNotInProject(Project project)
{
    List<string> returnValue = new List<string>();
    string startPath = Path.GetDirectoryName(project.FullName);
    List<string> projectFiles = GetAllProjectFiles(project.ProjectItems, ".cs");

    foreach (var file in Directory.GetFiles(startPath, "*.cs", SearchOption.AllDirectories))
        if (!projectFiles.Contains(file)) returnValue.Add(file);

    return returnValue;
}

答案 1 :(得分:8)

感谢@JaredPar和@lpthnc指出我正确的方向。我最终使用的方法非常类似于@JaredPar上面概述的方法。这是我的工作宏FWIW。

Imports System.IO
Imports System.Collections.Generic
Imports EnvDTE

Public Module Main

    Sub IncludeNewFiles()
        Dim Count As Integer = 0
        For Each Project As Project In DTE.Solution.Projects
            If Project.UniqueName.EndsWith(".vbproj") Then
                Dim NewFiles As List(Of String) = GetFilesNotInProject(Project)
                For Each File In NewFiles
                    Project.ProjectItems.AddFromFile(File)
                Next
                Count += NewFiles.Count
            End If
        Next
        DTE.StatusBar.Text = String.Format("{0} new file{1} included in the project.", Count, If(Count = 1, "", "s"))
    End Sub

    Private Function GetAllProjectFiles(ByVal ProjectItems As ProjectItems, ByVal Extension As String) As List(Of String)
        GetAllProjectFiles = New List(Of String)
        For Each ProjectItem As ProjectItem In ProjectItems
            For i As Integer = 1 To ProjectItem.FileCount
                Dim FileName As String = ProjectItem.FileNames(i)
                If Path.GetExtension(fileName).ToLower = Extension Then
                    GetAllProjectFiles.Add(fileName)
                End If
            Next
            GetAllProjectFiles.AddRange(GetAllProjectFiles(ProjectItem.ProjectItems, Extension))
        Next
    End Function

    Private Function GetFilesNotInProject(ByVal Project As Project) As List(Of String)
        Dim StartPath As String = Path.GetDirectoryName(Project.FullName)
        Dim ProjectFiles As List(Of String) = GetAllProjectFiles(Project.ProjectItems, ".vb")
        GetFilesNotInProject = New List(Of String)
        For Each file In Directory.GetFiles(StartPath, "*.vb", SearchOption.AllDirectories)
            If Not ProjectFiles.Contains(file) Then GetFilesNotInProject.Add(file)
        Next
    End Function

End Module

答案 2 :(得分:2)

我采取的方法是

  1. 枚举文件系统以查找所有文件
  2. 检查并查看给定文件是否具有关联的项目项。
  3. 以下是一些示例代码

    Function ContainsItem(p as Project, fileName as String) As Boolean
      Try
        Return p.ProjectItems.Item(fileName)
      Catch ex As ArgumentException
        Return False
      End Try
    End Function
    
    Function CotainsItem(dte as DTE, fileName as String) As Boolean
      For Each p As Project in dte.Solution.Projects
        Return ContainsItem(p, fileName)
      Next
    End Function
    
    Function GetFilesNotInProject(dte as DTE, startPath as String) as List(Of String)
      Dim list As New List(Of String)
      Dim files = Directory.GetFiles(startPath, "*.cs", SearchOPtions.AllDirectories)
      For Each file in files 
        If Not ContainsItem(dte, file) Then
          list.Add(file)
        End If
      Next
      Return list
    End Function
    

答案 3 :(得分:0)

我会选择PowerShell。我的另一篇文章中的PowerShell脚本将为您完成此操作。该脚本将从项目文件中获取包含文件的列表,并将其与磁盘上的文件进行比较。您将获得磁盘上但未包含在项目中的文件集。您可以删除它们或将它们作为TFS的删除删除。

https://stackoverflow.com/a/23420956/846428