2010-01-04 2 views
8

Я хотел бы написать макрос для сканирования через файлы в моем каталоге проектов и поиска файлов, которые не включены в проект.Visual Studio macro: найдите файлы, которые не включены в проект?

При игре вокруг объекта DTE я вижу, что объект Project имеет ProjectItems; если ProjectItem представляет собой каталог, то он имеет свою собственную коллекцию ProjectItems. Это дает мне все файлы, которые включены в проект.

Таким образом, я мог бы сканировать рекурсивно через каждую коллекцию ProjectItems, и для каждого ProjectItem, который является каталогом, проверьте, есть ли файлы в файловой системе, у которых нет соответствующего ProjectItem. Однако это кажется неуклюжим.

Любые идеи более простого способа приблизиться к этому?

+0

Получить список всех каталогов, участвующих, найти все файлы в них, сохранить их полные пути в структуру набора данных. Теперь просмотрите все файлы в вашем проекте и удалите их из набора (предварительно откройте правильный путь). Затем изучите, что у вас осталось ... –

+0

Спасибо - почему бы просто не опубликовать это как ответ? –

ответ

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

Будет ли это работать для всего решения. У меня есть множество исключенных файлов, которые я хочу удалить. –

+0

@SohamDasgupta - вам, вероятно, придется пройти через проекты решения один за другим и сделать это для каждого. –

+0

Кажется, что [Макросы больше не доступны в Visual Studio 2012] (http://www.dzone.com/articles/missing-macros-visual-studio). Любое возможное решение для VS 2012? –

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 ProjectItem по очереди. В коде, который я опубликовал, я создаю список существующих файлов, а затем использую его, чтобы увидеть, что не включено. –

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

Смежные вопросы