2010-01-04 15 views
8

Me gustaría escribir una macro para rastrear los archivos en el directorio de mi proyecto y encontrar archivos que no están incluidos en el proyecto.macro de Visual Studio: buscar archivos que no están incluidos en el proyecto?

Al jugar con el objeto DTE, veo que el objeto Project tiene ProjectItems; si un ProjectItem representa un directorio, entonces tiene su propia colección ProjectItems. Esto me da todos los archivos que están incluidos en el proyecto.

Para poder rastrear recursivamente a través de cada colección de ProjectItems, y para cada elemento de proyecto que sea un directorio, verifique si hay archivos en el sistema de archivos que no tienen un ProjectItem correspondiente. Esto parece torpe, sin embargo.

¿Alguna idea de una forma más sencilla de abordar esto?

+0

obtener una lista de todos los directorios implicados, encontrar todos los archivos en ellos, excepto sus rutas completas en una estructura de datos del conjunto. Ahora revise todos los archivos en su proyecto y elimínelos del conjunto (antes de colgar en el camino correcto). Luego examine lo que le sobra ... –

+0

Gracias, ¿por qué no publica esto como respuesta? –

Respuesta

8

Gracias a @JaredPar y @lpthnc para señalarme en la dirección correcta. Terminé usando un enfoque muy similar a lo que dice @JaredPar con anterioridad. Aquí está mi macro de trabajo 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

Funciona para toda la solución. Tengo muchos archivos excluidos que quiero eliminar. –

+0

@SohamDasgupta - probablemente tenga que recorrer los proyectos de la solución uno por uno, y hacer esto para cada uno. –

+0

Parece que [las macros ya no están disponibles en Visual Studio 2012] (http://www.dzone.com/articles/missing-macros-visual-studio). ¿Alguna solución posible para VS 2012? –

2

El enfoque me gustaría tener es

  1. enumerar el sistema de archivos en busca de todos los archivos
  2. comprobar y ver si el archivo dado tiene un elemento de proyecto asociado.

Aquí es un poco rápida de código de ejemplo

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

Gracias, esto ayudó mucho. No funciona del todo como está, porque 'p.ProjectItems' solo contiene elementos en la raíz del proyecto; tiene que volver a recurrir a través de cada colección propia de ProjectItem de ProjectItem. En el código que publiqué, construí una lista de archivos existentes y luego la usé para ver lo que no está incluido. –

11

Aquí está la versión # C de su código:

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

me gustaría ir con PowerShell. El script de PowerShell en mi otra publicación lo hará por usted. El script obtendrá la lista de archivos incluidos del archivo de proyecto y comparará eso con los archivos en el disco. Obtendrá el conjunto de archivos que están en el disco pero que no están incluidos en el proyecto. Puede eliminarlos o colgarlos como eliminaciones para TFS.

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

Cuestiones relacionadas