2010-01-04 27 views
8

Tôi muốn viết macro để thu thập dữ liệu thông qua các tệp trong thư mục dự án của tôi và tìm tệp không được đưa vào dự án.Macro của Visual Studio: Tìm tệp không được đưa vào dự án?

Khi chơi với vật thể DTE, tôi thấy đối tượng ProjectProjectItems; nếu ProjectItem đại diện cho một thư mục, thì thư mục có bộ sưu tập ProjectItems của riêng nó. Điều này mang lại cho tôi tất cả các tệp được bao gồm trong dự án.

Vì vậy, tôi có thể thu thập thông tin đệ quy thông qua mỗi bộ sưu tập ProjectItems và cho mỗi ProjectItem đó là một thư mục, hãy kiểm tra xem có tệp trong hệ thống tệp không có ProjectItem tương ứng hay không. Điều này có vẻ vụng về, mặc dù.

Bất kỳ ý tưởng nào về cách tiếp cận này đơn giản hơn?

+0

Lấy danh sách tất cả các thư mục liên quan, tìm mọi tệp trong đó, lưu toàn bộ đường dẫn vào cấu trúc dữ liệu đã đặt. Bây giờ đi qua tất cả các tập tin trong dự án của bạn và loại bỏ chúng khỏi tập hợp (pre-pend the right path). Sau đó kiểm tra những gì bạn đã để lại trên ... –

+0

Cảm ơn - tại sao không chỉ đăng bài này như là một câu trả lời? –

Trả lời

8

Nhờ @JaredPar và @lpthnc đã chỉ cho tôi đi đúng hướng. Tôi đã kết thúc bằng cách sử dụng một cách tiếp cận rất giống với những gì @JaredPar phác thảo ở trên. Đây là macro làm việc của tôi 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

Điều này có hiệu quả với toàn bộ giải pháp hay không. Tôi có vô số tệp bị loại trừ mà tôi muốn xóa. –

+0

@SohamDasgupta - bạn có thể phải đi qua từng dự án của một giải pháp và thực hiện việc này cho từng dự án. –

+0

Dường như [Macro không còn có sẵn trong Visual Studio 2012] (http://www.dzone.com/articles/missing-macros-visual-studio). Bất kỳ giải pháp khả thi nào cho VS 2012? –

2

Cách tiếp cận tôi sẽ thực hiện là để

  1. Liệt kê các file hệ thống tìm kiếm tất cả các file
  2. Kiểm tra và xem các tập tin được có một hạng mục công trình liên quan.

Dưới đây là một chút nhanh chóng mã mẫu

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

Cảm ơn - điều này đã giúp ích rất nhiều. Nó không hoàn toàn hoạt động như vậy, bởi vì 'p.ProjectItems' chỉ chứa các mục ở gốc của dự án; bạn phải kiểm tra lại từng bộ sưu tập ProjectItem của riêng ProjectItem. Trong mã tôi đã đăng, tôi xây dựng một danh sách các tập tin hiện có và sau đó sử dụng nó để xem những gì không được bao gồm. –

11

Dưới đây là C# phiên bản của mã của bạn:

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

Tôi muốn đi với PowerShell. Kịch bản PowerShell trong bài viết khác của tôi sẽ làm điều này cho bạn. Tập lệnh sẽ nhận danh sách các tệp được bao gồm từ tệp dự án và so sánh tệp đó với các tệp trên đĩa. Bạn sẽ nhận được tập hợp các tệp trên đĩa nhưng không có trong dự án. Bạn có thể xóa chúng hoặc đổi chúng thành xóa cho TFS.

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

Các vấn đề liên quan