2016-01-26 1 views
0

J'essaie de parcourir tous les projets de notre solution Visual Studio 2008 par programme afin de garantir les valeurs correctes de certains paramètres de projet. J'essaie de le faire avec VBS et DTE mais je n'insiste pas sur l'utilisation d'un langage/API/framework particulier, sauf que je n'aimerais pas apporter de réglages aux paramètres du projet au niveau XML. Le problème avec le code VBS suivant est qu'il ne rencontre aucun projet (comme ils sont tous contenus dans des dossiers de solution) - au lieu de cela, je reçois juste une liste des dossiers de solution.Comment effectuer une itération par programmation dans tous les projets de la solution Visual Studio 2008 en considérant les dossiers de solutions

Exemple sortie msgbox:

NAME:Gateways TYPE: {66A26720-8FB5-11D2-AA7E-00C04F688DDE} 

ci-dessus GUID est en fait la même chose pour tous les dossiers de solution.

solutionfile = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) + "\big_solution.sln" 
msgbox(solutionfile) 
Set dte = CreateObject("VisualStudio.DTE.9.0") 
dte.MainWindow.Visible = True 

Call dte.solution.open(solutionfile) 
Set prjs = DTE.Solution.Projects 
For i = 1 To prjs.Count 
    Set p = prjs.Item(i) 
    msgbox("NAME:" & p.Name & " TYPE: " & p.Kind & vbCr) 
Next 

Call dte.solution.SaveAs(dte.solution.FileName) 
dte.solution.close 

msgbox solutionfile + " successfully updated." 

dte.UserControl = True 

Merci pour tous les conseils!

Répondre

1

Pour travailler avec des solutions VS2008, vous devez d'abord

c: \ Program Files (x86) \ Microsoft Visual Studio 9.0 \ Common7 \ IDE \ PublicAssemblies \ EnvDTE.dll

mais elle n'expose pas toutes les propriétés de tous les types de projets (par exemple, la propriété "InheritedPropertySheets" dans les projets C++ n'est pas accessible). Pour accéder à des projets C++ correctement, vous aurez également besoin:

c: \ Program Files (x86) \ Microsoft Visual Studio 9.0 \ Common7 \ IDE \ PublicAssemblies \ Microsoft.VisualStudio.VCProjectEngine.dll

Exemple en C# (.NET 3.5) qui traverse une solution, en s'assurant que chaque projet C++ hérite de notre Property Sheet personnalisé puis, dans l'étape Post-Build, utilise la macro "THETARGETDIR" qui est définie de manière centrale dans notre feuille de propriétés.

using System; 
using System.Runtime.InteropServices; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using EnvDTE; 
using Microsoft.VisualStudio.VCProjectEngine; 

namespace FixSolution 
{ 
    class Program 
    { 
     private class Stats 
     { 
      public int n_pbs_adjusted = 0; 
      public int n_projects = 0; 
      public int n_projects_cpp = 0; 
      public int n_ps_adjusted = 0; 
      public int n_consistency_errors = 0; 
     } 
     private static Stats _stats = new Stats(); 

     static void ProcessSolutionFolder(Project p) 
     { 
      foreach (ProjectItem pi in p.ProjectItems) 
      { 
       Project pp = pi.Object as Project; 
       if (pp == null) 
       { 
        continue; // solution item but not a project (e.g. big_solution_explained.txt) 
       } 

       if (pp.Kind == FixSolution.Properties.Settings.Default.SF_GUID) 
        ProcessSolutionFolder(pp); 
       else 
        ProcessProject(pp); 
      } 
     } 

     private static int NextHardcoded(string cmd) 
     { 
      return cmd.ToLower().IndexOf(FixSolution.Properties.Settings.Default.STD_TARGET); 
     } 

     private static bool ProcessVCPostBuildEventTool(VCConfiguration c) 
     { 
      IVCCollection cc = c.Tools as IVCCollection; 
      if (cc == null) return false; 
      bool adjusted = false; 
      foreach (Object tool in cc) 
      { 
       VCPostBuildEventTool pbs = tool as VCPostBuildEventTool; 
       if (pbs == null || pbs.CommandLine == null) continue; 

       int pos = NextHardcoded(pbs.CommandLine); 
       var before_adjustment = pbs.CommandLine; 
       while (pos != -1) 
       { 
        adjusted = true; 
        string CMD = pbs.CommandLine; 
        int tl = FixSolution.Properties.Settings.Default.STD_TARGET.Length; 
        pbs.CommandLine = CMD.Substring(0, pos) + "$(THETARGETDIR)" + CMD.Substring(pos + tl, CMD.Length - pos - tl); 

        pos = NextHardcoded(pbs.CommandLine); 
       } 

       if (adjusted) 
       { 
        VCProject p = c.project as VCProject; 
        Console.WriteLine("\nWARNING: project " + p.ProjectFile 
         + "\nConfiguration " + c.ConfigurationName + " contains hardcoded sophis directory in PBS:" 
         + "\n" + before_adjustment); 
        Console.WriteLine("REPLACED BY:"); 
        Console.WriteLine(pbs.CommandLine); 
       } 
      } 
      return adjusted; 
     } 

     private static void ProcessProject(Project pp) 
     { 
      ++_stats.n_projects; 
      VCProject p = pp.Object as VCProject; 
      if (p == null) 
       return; // not a C++ project 

      ++_stats.n_projects_cpp; 
      string vsprops_path = Util.GetRelativePath(p.ProjectDirectory, FixSolution.Properties.Settings.Default.AbsoluteVspropsPath); 

      bool adjusted_ps = false; 
      bool adjusted_pbs = false; 

      foreach (VCConfiguration c in (IVCCollection)p.Configurations) 
      { 
       if (ProcessVCPostBuildEventTool(c)) 
        adjusted_pbs = true; 

       if (c.InheritedPropertySheets == vsprops_path) 
       { 
        continue; 
       } 
       if (c.InheritedPropertySheets.Length > 0) 
       { 
        Console.WriteLine("WARNING: project " + pp.FullName + " config " + c.Name + " has unusual InheritedPropertySheets: " + c.InheritedPropertySheets); 
        ++_stats.n_consistency_errors; // counting the unexpected, per configuration 
       } 
       adjusted_ps = true; 
       c.InheritedPropertySheets = vsprops_path; 
      } 

      if (adjusted_ps) 
       ++_stats.n_ps_adjusted; 
      if (adjusted_pbs) 
       ++_stats.n_pbs_adjusted; 

      p.Save(); 
     } 

     static DTE GetDTE(string solutionfile) 
     { 
      DTE dte = null; 
      try 
      {     
       dte = (DTE)System.Runtime.InteropServices.Marshal.GetActiveObject(
        FixSolution.Properties.Settings.Default.ROT_PROG_ID); 
      } 
      catch (Exception) 
      { 
       Console.WriteLine("Could not get an instance of an already running Visual Studio. Trying to start a new one"); 
      } 
      if (dte == null) 
      { 
       Type visualStudioType = Type.GetTypeFromProgID(
        FixSolution.Properties.Settings.Default.ROT_PROG_ID); 
       dte = Activator.CreateInstance(visualStudioType) as DTE; 
      } 
      if (dte == null) 
      { 
       Console.WriteLine("Unable to get an instance of Visual Studio"); 
      } 
      else 
      { 
       dte.MainWindow.Visible = true; 
       dte.Solution.Open(solutionfile); 
      } 
      return dte; 
     } 

     static void ProcessSolution(string solutionfile) 
     { 
      DTE dte = GetDTE(solutionfile); 

      foreach (Project pp in dte.Solution.Projects) 
      { 
       if (pp.Kind == FixSolution.Properties.Settings.Default.SF_GUID) 
        ProcessSolutionFolder(pp); 
       else 
        ProcessProject(pp); 
      } 
      Console.WriteLine(string.Format("\nn_projects={0}, n_projects_cpp={1}, n_pbs_adjusted={2}, n_ps_adjusted={3}; n_consistency_errors={4}", 
       _stats.n_projects, _stats.n_projects_cpp, _stats.n_pbs_adjusted, _stats.n_ps_adjusted, _stats.n_consistency_errors)); 
      dte.Solution.Close(); 
     } 

     static void Main(string[] args) 
     { 
      if (args.Length == 0) 
      { 
       Console.WriteLine(@"Usage: FixSolution c:\full\path\to\YourSolution.sln"); 
      } 

      var solutionfile = args[0]; 

      ProcessSolution(solutionfile); 
     } 
    } 
} 

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > 
      <section name="FixSolution.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
     </sectionGroup> 
    </configSections> 
    <applicationSettings> 
     <FixSolution.Properties.Settings> 
      <setting name="AbsoluteVspropsPath" serializeAs="String"> 
       <value>c:\svn\mainline\ourbuild.vsprops</value> 
      </setting> 
      <setting name="SF_GUID" serializeAs="String"> 
       <value>{66A26720-8FB5-11D2-AA7E-00C04F688DDE}</value> 
      </setting> 
      <setting name="STD_TARGET" serializeAs="String"> 
       <value>c:\apps\ourapp</value> 
      </setting> 
      <setting name="ROT_PROG_ID" serializeAs="String"> 
       <value>VisualStudio.DTE.9.0</value> 
      </setting> 
     </FixSolution.Properties.Settings> 
    </applicationSettings> 
</configuration> 

ourbuild.vsprops

<?xml version="1.0" encoding="Windows-1252"?> 
<VisualStudioPropertySheet 
    ProjectType="Visual C++" 
    Version="8.00" 
    Name="build" 
    > 
    <UserMacro 
     Name="THETARGETDIR" 
     Value="c:\apps\ourapp" 
     PerformEnvironmentSet="true" 
    /> 
</VisualStudioPropertySheet>