2013-10-17 2 views
12

Je suis en train de développer un outil personnalisé pour Visual Studio. L'outil est assigné au fichier, au moment où le fichier a changé, je reçois le nom de ce fichier et devrait générer quelques changements dans le projet. J'ai besoin de trouver un ProjectItem par le nom de fichier reçu. Je n'ai trouvé qu'une seule solution: énumérer tous les éléments du projet dans chaque projet de la solution. Mais il semble être une solution énorme. Existe-t-il un moyen d'obtenir un élément de projet par le nom de fichier sans énumération?Comment trouver un ProjectItem par le nom de fichier

C'est ma mise en œuvre de la méthode Générer du IVsSingleFileGenerator

public int Generate(string sourceFilePath, string sourceFileContent, string defaultNamespace, IntPtr[] outputFileContents, out uint output, IVsGeneratorProgress generateProgress) 
{ 
    var dte = (EnvDTE.DTE)Package.GetGlobalService(typeof(EnvDTE.DTE)); 

    ProjectItem projectItem = null; 

    foreach (Project project in dte.Solution.Projects) 
    { 
     foreach (ProjectItem item in project.ProjectItems) 
     { 
      var path = item.Properties.Item("FullPath").Value; 
      if (sourceFilePath.Equals(path, StringComparison.OrdinalIgnoreCase)) 
      { 
       projectItem = item; 
      } 
     }    
    } 

    output = 0; 
    outputFileContents[0] = IntPtr.Zero; 

    return Microsoft.VisualStudio.VSConstants.S_OK; 
} 
+0

Pas clair: Êtes-vous l'analyse du fichier sln, puis l'analyse de chaque csproj? Ou êtes-vous en train de scanner le système de fichiers? –

+1

Je recherche dans l'objet DTE fourni par VisualStudio. –

+0

Cela semble fonctionner: https://stackoverflow.com/a/38876595/509584 –

Répondre

7

J'utilise ce monde de DTE et convivial , pour créer une orientation. Je n'ai pas trouvé de meilleure solution. Fondamentalement, ce sont des méthodes que je utilise:

projets de Iterate:

public static ProjectItem FindSolutionItemByName(DTE dte, string name, bool recursive) 
{ 
    ProjectItem projectItem = null; 
    foreach (Project project in dte.Solution.Projects) 
    { 
     projectItem = FindProjectItemInProject(project, name, recursive); 

     if (projectItem != null) 
     { 
      break; 
     } 
    } 
    return projectItem; 
} 

trouver dans un seul projet:

public static ProjectItem FindProjectItemInProject(Project project, string name, bool recursive) 
{ 
    ProjectItem projectItem = null; 

    if (project.Kind != Constants.vsProjectKindSolutionItems) 
    { 
     if (project.ProjectItems != null && project.ProjectItems.Count > 0) 
     { 
      projectItem = DteHelper.FindItemByName(project.ProjectItems, name, recursive); 
     } 
    } 
    else 
    { 
     // if solution folder, one of its ProjectItems might be a real project 
     foreach (ProjectItem item in project.ProjectItems) 
     { 
      Project realProject = item.Object as Project; 

      if (realProject != null) 
      { 
       projectItem = FindProjectItemInProject(realProject, name, recursive); 

       if (projectItem != null) 
       { 
        break; 
       } 
      } 
     } 
    } 

    return projectItem; 
} 

Le code que je utilise avec plus des extraits pourraient être trouvés here, comme Guide pour les nouveaux projets. Rechercher et prendre le code source ..

+1

comme un avertissement cela ne compte pas du tout pour les dossiers de solution. 'dteSolution.Projects' renvoie uniquement les éléments de niveau supérieur, pas les projets qui sont dans les dossiers de solution = ( – Maslow

+4

Je vois que c'est vieux, mais cela devrait vraiment avoir le code (ou la référence) à 'DteHelper.FindItemByName()'. –

+4

** DteHelper ** n'est pas un code personnalisé, mais Microsoft - intégré. Ce serait un nom complet: ** 'Microsoft.Practices.RecipeFramework.Library.DteHelper' ** –

Questions connexes