8

プロジェクトディレクトリ内のファイルをクロールして、プロジェクトに含まれていないファイルを見つけるためのマクロを作成したいと思います。

DTEオブジェクトをいじってみると、ProjectオブジェクトにはProjectItems;があることがわかります。aがディレクトリを表す場合、ProjectItemそれは独自のProjectItemsコレクションを持っています。これにより、プロジェクトに含まれるすべてのファイルが得られます。

したがって、各ProjectItemsコレクションを再帰的にクロールし、ディレクトリである各ProjectItemについて、対応するProjectItemを持たないファイルがファイルシステムにあるかどうかを確認します。しかし、これは不器用に思えます。

これにアプローチするためのより簡単な方法のアイデアはありますか?

4

4 に答える 4

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;
}
于 2012-02-26T22:19:42.110 に答える
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
于 2010-01-04T16:50:43.210 に答える
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
于 2010-01-04T15:43:08.967 に答える
0

PowerShellを使用します。私の他の投稿のPowerShellスクリプトは、これを行います。スクリプトは、プロジェクトファイルから含まれているファイルのリストを取得し、それをディスク上のファイルと比較します。ディスク上にあるがプロジェクトに含まれていないファイルのセットを取得します。それらを削除するか、TFSの削除として保留することができます。

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

于 2014-05-02T05:12:38.683 に答える