我正在尝试以编程方式浏览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
感谢任何提示!
答案 0 :(得分: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 Step中使用宏" 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>