2016-01-26 10 views
0

Я пытаюсь программно реализовать все проекты нашего решения Visual Studio 2008, чтобы обеспечить правильные значения определенных параметров проекта.Как программно перепрограммировать все проекты решения Visual Studio 2008 с учетом решений Пакеты

Я пытаюсь сделать это с помощью VBS и DTE, но я не настаиваю на использовании определенного языка/API/фреймворка, за исключением того, что я не хотел бы вносить коррективы в настройки проекта на уровне XML.

Проблема со следующим кодом VBS заключается в том, что он не сталкивается с проектами (поскольку все они содержатся в папках решений) - вместо этого я просто получаю список папок решений.

Пример вывода MsgBox:

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

выше GUID фактически одинаковы для всех папок решения.

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 

Благодарим за любые намеки!

ответ

1

Для работы с VS2008 решений, вам необходимо в первую очередь

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

но он не отображает все свойства всех видов проектов (например, свойство «InheritedPropertySheets» в проектах на C++ недоступно). Чтобы получить доступ к C++ проектов правильно, вы также должны:

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

Пример в C# (.NET 3.5), который пересекает решение, убедившись, что каждый проект C++ наследует наш пользовательский Property Sheet, а затем на этапе Post-Build используется макрос «THETARGETDIR», который определяется централизованно в нашем листе свойств.

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> 

 Смежные вопросы

  • Нет связанных вопросов^_^