views:

621

answers:

1

Environment:

C# projects, Visual studio 2008, C#, .Net 3.5, MSBuild

Objective:

Run my own custom build task for my C# projects, and based on the platform (Soln configuration platform), I do some manipulations to the Project object itself before build. Like setting BuildAction to EmbeddedResource etc.

Once that's done I call Project.Build(). I don't want to use the Project object on the GlobalEngine, because it is going to mark the file dirty (and checkout from TFS), once you modify the Project object in anyway.

Problem:

Because I am using my own instance of the Engine, and Project, I am not able to direct the build output, errors to VS. I only get a bool out of Project.Build(). I don't find any events I could hook up to that can allow access to BuildErrorEventArgs and things like that. I know I can use Log.LogErrorEvent() to log messages to VS error list. But I need to get the build output itself first to do that.

Code:

// Execute method in my custom build task class, derives from a BaseTask class
public override bool Execute()
{
Engine engine = new Engine();
Project project = new Project(engine);
project.Load(ProjectName);
Log.LogMessage(Microsoft.Build.Framework.MessageImportance.High, "Got the Project");
// Set the project's DefaultTargets to "Build" to be able to build with CSharp targets
project.DefaultTargets = "Build";
IsBuilt = project.Build(); // Isbuilt bool is a property in my BaseTask class
// Here's where I want to get Build output and direct it to VS output window and errorlist window

engine.Shutdown();
return base.Execute();
}
+2  A: 

I figured it out, simply implement a custom logger and use Log.LogMessage or LogError in the event handlers

public class MyCustomBuildLogger : ILogger
{
    private IEventSource source;

 public void Initialize(IEventSource eventSource)
        {
            this.source = eventSource;
            //Events.ProjectStarted += new ProjectStartedEventHandler(Events_ProjectStarted);
            //Events.ProjectFinished += new ProjectFinishedEventHandler(Events_ProjectFinished);
            Events.WarningRaised += new BuildWarningEventHandler(Events_WarningRaised);
            Events.ErrorRaised += new BuildErrorEventHandler(Events_ErrorRaised);
            Events.BuildFinished += new BuildFinishedEventHandler(Events_BuildFinished);
            //Events.BuildStarted += new BuildStartedEventHandler(Events_BuildStarted);
            Events.MessageRaised += new BuildMessageEventHandler(Events_MessageRaised);
            //Events.CustomEventRaised += new CustomBuildEventHandler(Events_CustomEventRaised);

            Events.MessageRaised += new BuildMessageEventHandler(Events_MessageRaised);
        }

 void Events_ErrorRaised(object sender, BuildErrorEventArgs e)
        {
            // This logs the error to VS Error List tool window
            Log.LogError(String.Empty, 


             String.Empty,
                    String.Empty, 
                    e.File, 
                    e.LineNumber, 
                    e.ColumnNumber,
                    e.LineNumber, 
                    e.ColumnNumber, 
                    e.Message);
           }
}

and in the MyCustomBuildTask class, where you setup and load the engine and project,

_logger = new MyCustomBuildLogger();
_logger.Log = Log;
_engine.RegisterLogger(_logger);
Vin