将MSBuild生成的文件添加到Visual Studio解决方案资源管理器中

3
我有几个MSBuild任务,在构建期间生成新文件。自定义目标在生成后将文件添加到编译ItemGroup中。因此,如果运行我的目标,则构建将正常工作,但我想使用MSBuild的增量构建功能,并在自上次构建以来文件未被修改时跳过这些目标。但是,如果构建跳过目标,则生成的文件将不会包括在内。
因此,我希望将生成的文件添加到解决方案资源管理器中。我意识到可以手动添加文件,但这可能是我必须走的路线,但我真的很想通过编程方式添加生成的文件。
我目前有一个名为Custom.targets的文件。它包含在每个项目中并注入新目标。我尝试将*.cs包含在项目中,但那样做没有起作用。

1
这些将是 csproj 文件中的条目。 - Andy Eskridge
你可以在这里查看我为自己的问题留下的答案:https://dev59.com/MWzXa4cB1Zd3GeqPPg9U。我使用了Msbuild(xmlupdate)任务通过msbuild代码添加“链接文件”。 - granadaCoder
哎呀,我添加了一个链接文件......你可以修改我的代码以添加任何你想要的内容......但前提是......你只需调用任务来操作xml。我会获取我使用的目标源代码,这样就能理解正在发生的事情......通过DOM操作。 - granadaCoder
我认为如果在你的 *.csproj 文件中通过 Custom.targets 导入了 Targets,并在 BeforeBuild 中调用它们,然后添加如下的 Compile ItemGroup,将包含任何由 Custom.targets 生成的 *.cs 文件到 *.csproj 文件夹或该文件夹下的任何文件夹中。 <Compile Include="**\*.cs" />。如果你想要去到 *csproj 文件夹上一级的文件夹,那么尝试 <Compile Include="..\**\*.cs" />。句号数量 ..\\ 取决于你想向上转到的文件夹级数。 - RinoTom
@RinoTom 这可以确保在构建过程中引用任何已生成的文件。但这并不会将文件添加到Visual Studio资源管理器中。这会导致智能感知抱怨缺少实际存在但隐藏在生成文件中的方法。granadaCoder 我认为你不能在运行.csproj文件时编辑它们?你是否有一个单独的msbuild脚本来修改你的csproj文件? - Andy Eskridge
显示剩余2条评论
1个回答

0
我最终做了一些类似于granadaCoder的事情。 我决定在自定义任务中执行它,而不仅仅是在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;
        }
    }
}

为什么不允许异常向上抛出? - Evgeny Gorbovoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接