8

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

在玩弄 DTE 对象时,我看到该Project对象有ProjectItems; 如果 aProjectItem代表一个目录,那么它有自己的ProjectItems集合。这给了我项目中包含的所有文件。

因此,我可以递归地爬取每个 ProjectItems 集合,并且对于作为目录的每个 ProjectItem,检查文件系统中是否存在没有相应 ProjectItem 的文件。不过,这似乎很笨拙。

有什么更简单的方法来解决这个问题吗?

4

4 回答 4

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;
}
于 2012-02-26T22:19:42.110 回答
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
于 2010-01-04T16:50:43.210 回答
2

我会采取的方法是

  1. 枚举文件系统查找所有文件
  2. 检查并查看给定文件是否具有关联的项目项。

这是一个快速的示例代码

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
于 2010-01-04T15:43:08.967 回答
0

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

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

于 2014-05-02T05:12:38.683 回答