Arhn - архитектура программирования

Макрос Visual Studio: найти файлы, не включенные в проект?

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

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

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

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


  • Получите список всех задействованных каталогов, найдите в них каждый файл, сохраните их полные пути в установленной структуре данных. Теперь просмотрите все файлы в вашем проекте и удалите их из набора (предварительно указав правильный путь). Затем осмотрите то, что у вас осталось... 04.01.2010
  • Спасибо - почему бы просто не опубликовать это как ответ? 04.01.2010

Ответы:


1

Вот версия вашего кода на С#:

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

2

Спасибо @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
04.01.2010
  • Будет ли это работать для всего решения. У меня есть множество исключенных файлов, которые я хочу удалить. 17.07.2012
  • @SohamDasgupta - вам, вероятно, придется просматривать проекты решения один за другим и делать это для каждого. 23.07.2012
  • Похоже, что макросы больше не доступны в Visual Studio 2012. Любое возможное решение для VS 2012? 19.08.2013

  • 3

    Подход, который я бы выбрал, заключается в

    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
    
    04.01.2010
  • Спасибо - это очень помогло. Это не совсем работает как есть, потому что p.ProjectItems содержит только элементы в корне проекта; вы должны по очереди пройти через собственную коллекцию ProjectItems каждого ProjectItem. В коде, который я разместил, я создаю список существующих файлов, а затем использую его, чтобы увидеть, что не включено. 04.01.2010

  • 4

    Я бы пошел с PowerShell. Сценарий PowerShell в моем другом посте сделает это за вас. Скрипт получит список включенных файлов из файла проекта и сравнит его с файлами на диске. Вы получите набор файлов, которые есть на диске, но не включены в проект. Вы можете либо удалить их, либо приостановить их удаление для TFS.

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

    02.05.2014
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..