C# 将MSBuild生成的文件添加到Visual Studio解决方案资源管理器
我有两个MSBuild任务,它们在生成过程中生成新文件。自定义目标会在生成文件后将其添加到Compile ItemGroup。因此,如果运行了我的目标,构建将正常工作,但如果自上次构建以来文件未被修改,我希望使用MSBuild的增量构建功能并跳过这些目标。但是,如果构建跳过了目标,那么生成的文件将不会包括在内 因此,我想让构建将文件添加到解决方案资源管理器中。我意识到我可以手动添加文件,这可能是我必须走的路线,但我真的希望以编程方式添加生成的文件C# 将MSBuild生成的文件添加到Visual Studio解决方案资源管理器,c#,visual-studio,visual-studio-2012,msbuild,C#,Visual Studio,Visual Studio 2012,Msbuild,我有两个MSBuild任务,它们在生成过程中生成新文件。自定义目标会在生成文件后将其添加到Compile ItemGroup。因此,如果运行了我的目标,构建将正常工作,但如果自上次构建以来文件未被修改,我希望使用MSBuild的增量构建功能并跳过这些目标。但是,如果构建跳过了目标,那么生成的文件将不会包括在内 因此,我想让构建将文件添加到解决方案资源管理器中。我意识到我可以手动添加文件,这可能是我必须走的路线,但我真的希望以编程方式添加生成的文件 我目前有一个名为Custom.targets的文
我目前有一个名为Custom.targets的文件。它包含在每个项目中,并注入新的目标。我曾尝试在项目中包括*.cs,但没有成功。我最终做了一些类似于GranadCoder的事情。我只是决定在自定义任务中完成它,而不仅仅是在xml中。我确保项目中包含3个文件:FilePath、BinPath和HooksPath。如果他们都在那里,什么也不会发生。如果缺少一个,则将其添加到ItemGroup并保存文档。生成期间无法保存文档。因此,需要在任何保存后再次运行构建
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace BuildTasks
{
public class AddFilesToProject : Task
{
[Required]
public string ProjectPath { get; set; }
[Required]
public string FilePath { get; set; }
[Required]
public string BinPath { get; set; }
[Required]
public string HooksPath { get; set; }
[Required]
public string ProjectDir { get; set; }
/// <summary>
/// When overridden in a derived class, executes the task.
/// </summary>
/// <returns>
/// true if the task successfully executed; otherwise, false.
/// </returns>
public override bool Execute()
{
try
{
var binRelative = BinPath.Replace(ProjectDir + "\\", "");
var hooksRelative = HooksPath.Replace(ProjectDir + "\\", "");
var fileRelative = FilePath.Replace(ProjectDir + "\\", "");
XDocument document = XDocument.Load(ProjectPath);
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
bool foundBin = false;
bool foundHooks = false;
bool foundFile = false;
XElement itemGroup = null;
foreach (XElement el in document.Descendants(ns + "ItemGroup"))
{
foreach (XElement item in el.Descendants(ns + "Compile"))
{
itemGroup = el;
if (item.Attribute("Include").Value.Contains(binRelative))
{
foundBin = true;
Log.LogMessage(MessageImportance.Low, "FoundBin: {0}", foundBin);
}
else if (item.Attribute("Include").Value.Contains(hooksRelative))
{
foundHooks = true;
Log.LogMessage(MessageImportance.Low, "FoundHooks: {0}", foundHooks);
}
else if (item.Attribute("Include").Value.Contains(fileRelative))
{
foundFile = true;
Log.LogMessage(MessageImportance.Low, "FoundFile: {0}", foundFile);
}
}
}
if (!foundBin)
{
XElement item = new XElement(ns + "Compile");
item.SetAttributeValue("Include", binRelative);
if (itemGroup != null) itemGroup.Add(item);
}
if (!foundHooks)
{
XElement item = new XElement(ns + "Compile");
item.SetAttributeValue("Include", hooksRelative);
if (itemGroup != null) itemGroup.Add(item);
}
if (!foundFile)
{
XElement item = new XElement(ns + "Compile");
item.SetAttributeValue("Include", fileRelative);
if (itemGroup != null) itemGroup.Add(item);
}
if (!foundBin || !foundHooks || !foundFile)
{
document.Save(ProjectPath);
}
}
catch (Exception e)
{
Log.LogErrorFromException(e);
}
return !Log.HasLoggedErrors;
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
使用System.Xml.Linq;
使用Microsoft.Build.Framework;
使用Microsoft.Build.Utilities;
命名空间构建任务
{
公共类AddFilesToProject:任务
{
[必需]
公共字符串项目路径{get;set;}
[必需]
公共字符串文件路径{get;set;}
[必需]
公共字符串BinPath{get;set;}
[必需]
公共字符串HooksPath{get;set;}
[必需]
公共字符串ProjectDir{get;set;}
///
///在派生类中重写时,执行任务。
///
///
///如果任务成功执行,则为true;否则为false。
///
公共重写bool Execute()
{
尝试
{
var binRelative=BinPath.Replace(ProjectDir+“\\”,“”);
var hooksRelative=HooksPath.Replace(ProjectDir+“\\”,“”);
var fileRelative=FilePath.Replace(ProjectDir+“\\”,“”);
XDocument document=XDocument.Load(项目路径);
XNS=”http://schemas.microsoft.com/developer/msbuild/2003";
bool-foundBin=false;
bool=false;
bool foundFile=false;
XElement itemGroup=null;
foreach(document.substands中的XElement el(ns+“ItemGroup”))
{
foreach(el.substands中的XElement项(ns+“编译”))
{
项目组=el;
if(item.Attribute(“Include”).Value.Contains(binRelative))
{
foundBin=true;
LogMessage(MessageImportance.Low,“FoundBin:{0}”,FoundBin);
}
else if(item.Attribute(“Include”).Value.Contains(hooksRelative))
{
foundHooks=true;
LogMessage(MessageImportance.Low,“FoundHooks:{0}”,FoundHooks);
}
else if(item.Attribute(“Include”).Value.Contains(fileRelative))
{
foundFile=true;
LogMessage(MessageImportance.Low,“FoundFile:{0}”,FoundFile);
}
}
}
如果(!foundBin)
{
XElement项=新XElement(ns+“编译”);
item.SetAttributeValue(“包括”,binRelative);
如果(itemGroup!=null)itemGroup.Add(item);
}
如果(!foundHooks)
{
XElement项=新XElement(ns+“编译”);
item.SetAttributeValue(“包括”,hooksRelative);
如果(itemGroup!=null)itemGroup.Add(item);
}
如果(!foundFile)
{
XElement项=新XElement(ns+“编译”);
item.SetAttributeValue(“包括”,fileRelative);
如果(itemGroup!=null)itemGroup.Add(item);
}
如果(!foundBin | | |!foundHooks | |!foundFile)
{
文档保存(ProjectPath);
}
}
捕获(例外e)
{
Log.LogErrorFromException(e);
}
return!Log.HasLoggedErrors;
}
}
}
您是说在csproj文件中添加“条目”吗?还是.sln文件?或者什么?这些将是csproj文件中的条目。您可以按照这里的答案(这是我留给我自己的问题的答案):我使用Msbuild(xmlupdate)任务通过Msbuild code.Ooops添加“链接文件”。我添加了一个链接文件……你可以修改我的代码来添加你想要的任何内容。。。。。。。但前提是。。。您只需调用任务来操作xml。我会得到我使用的目标的源代码,通过DOM操作,它对正在发生的事情是有意义的。我认为,如果您在*.csproj
文件中调用通过Custom.Targets
导入的Targets
,然后添加Compile
项目组
,如下所示,将包括任何获得的*.cs
文件由自定义.targets
生成到*.csproj
文件文件夹或该文件夹下的任何文件夹中<代码>。如果你想转到上面的文件夹