2010-01-04 136 views
8

我想編寫一個宏來抓取我的項目目錄中的文件,並查找未包含在項目中的文件。Visual Studio宏:查找未包含在項目中的文件?

在玩弄DTE對象時,我看到Project對象有ProjectItems;如果一個ProjectItem表示一個目錄,那麼它有它自己的ProjectItems集合。這給我包含在項目中的所有文件。

因此,我可以通過每個ProjectItems集合遞歸爬取,並且對於每個是目錄的ProjectItem,檢查文件系統中是否存在沒有相應ProjectItem的文件。雖然這看起來很笨拙。

任何想法更簡單的方法來解決這個問題?

+0

涉足的所有目錄的列表中,找到他們每個文件,其完整路徑保存到一組數據結構。現在瀏覽項目中的所有文件,並從集合中刪除它們(預先設置正確的路徑)。然後檢查你有什麼...... – 2010-01-04 15:30:51

+0

謝謝 - 爲什麼不只是發佈這個答案? – 2010-01-04 15:59:16

回答

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 
+0

這是否適用於整個解決方案。我有大量我想刪除的排除文件。 – 2012-07-17 06:00:12

+0

@SohamDasgupta - 您可能必須逐個瀏覽解決方案的項目,併爲每個項目執行此操作。 – 2012-07-23 15:29:19

+0

似乎[宏在Visual Studio 2012中不再可用](http://www.dzone.com/articles/missing-macros-visual-studio)。 VS 2012的任何可能的解決方案? – 2013-08-19 19:20:56

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 
+0

謝謝 - 這幫了很多。它不像現在這樣工作,因爲'p.ProjectItems'只包含項目根目錄中的項目;您必須依次遞增每個ProjectItem自己的ProjectItems集合。在我發佈的代碼中,我創建了一個現有文件列表,然後用它來查看未包含的內容。 – 2010-01-04 16:53:49

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; 
} 
0

我會使用PowerShell去。我另一篇文章中的PowerShell腳本會爲你做這件事。該腳本將從項目文件中獲取包含文件的列表,並將其與磁盤上的文件進行比較。您將獲得磁盤上但未包含在項目中的一組文件。您可以刪除它們,也可以將它們作爲TFS的刪除對象。

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

相關問題