将 MSBuild 生成的文件添加到 Visual Studio Solution Explorer

本文关键字:Visual Studio Solution Explorer 添加 文件 MSBuild | 更新日期: 2023-09-27 18:34:23

我有几个MSBuild任务,可以在构建过程中生成新文件。自定义目标在生成文件后将文件添加到编译项组。因此,如果我的目标已运行,则生成将起作用,但我想使用 MSBuild 的增量生成功能,如果自上次生成以来文件未被修改,则跳过这些目标。但是,如果构建跳过目标,则生成的文件将不包括在内。

因此,我想让构建将文件添加到解决方案资源管理器中。我意识到我可以手动添加文件,这可能是我必须走的路线,但我真的很想以编程方式添加生成的文件。

我目前有一个名为Custom.targets的文件。它包含在每个项目中并注入新的目标。我尝试在项目中包括 *.cs,但这不起作用。

将 MSBuild 生成的文件添加到 Visual Studio Solution Explorer

我最终做了一些类似于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;
        }
    }
}