简体   繁体   中英

Adding MSBuild generated files to Visual Studio Solution Explorer

I have a couple of MSBuild tasks that generate new files during the build. The custom targets add the files to the Compile ItemGroup after they are generated. So the build will work if my targets are ran, but I want to use the incremental building features of MSBuild and skip these targets if the files haven't been modified since the last build. But if the build skips the target the generated files won't be included.

So I want to have the build add the files to the solution explorer. I realize I can add the files manually, and that might be the route I have to go, but I would really like to have the generated files added programmatically.

I currently have a file called Custom.targets. It is included in every project and injects the new targets. I have tried including *.cs in the project, but that did not work.

I ended up doing something similar to granadaCoder. I just decided to do it inside of a custom task instead of only in xml. I ensure that 3 files are included in the project, FilePath, BinPath and HooksPath. If all of them are there, nothing happens. If it is missing one it adds it to the ItemGroup and saves the document. The document save can't happen during a build. So it requires running the build again after any save.

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;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM