将 MSBuild 生成的文件添加到 Visual Studio Solution Explorer
本文关键字:Visual Studio Solution Explorer 添加 文件 MSBuild | 更新日期: 2023-09-27 18:34:23
我有几个MSBuild任务,可以在构建过程中生成新文件。自定义目标在生成文件后将文件添加到编译项组。因此,如果我的目标已运行,则生成将起作用,但我想使用 MSBuild 的增量生成功能,如果自上次生成以来文件未被修改,则跳过这些目标。但是,如果构建跳过目标,则生成的文件将不包括在内。
因此,我想让构建将文件添加到解决方案资源管理器中。我意识到我可以手动添加文件,这可能是我必须走的路线,但我真的很想以编程方式添加生成的文件。
我目前有一个名为Custom.targets的文件。它包含在每个项目中并注入新的目标。我尝试在项目中包括 *.cs,但这不起作用。

我最终做了一些类似于granadaCoder的事情。我只是决定在自定义任务中执行此操作,而不仅仅是在 xml 中执行此操作。我确保项目中包含 3 个文件,FilePath、BinPath 和 HooksPath。如果所有人都在那里,什么都不会发生。如果缺少一个,则将其添加到项组并保存文档。文档保存不能在生成期间发生。因此,它需要在保存后再次运行构建。
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;
}
}
}