Abdalla
Abdalla

Reputation: 2073

How to build a csproj file using .net 2.0 MSBuild programmatically?

I am using unity so I have to stick with .net 2.0. I have copied the following files from the following path to my Assets/Editor folder

Unity\Editor\Data\Mono\lib\mono\2.0\

Microsoft.Build.Engine.dll

Microsoft.Build.Framework.dll

Microsoft.Build.Tasks.dll

Microsoft.Build.Utilities.dll

I tried to figure out my self how to do it, but most examples on the web uses newer MSBuild version, mostly MSBuild 4.0 and up.

I tried the following code, but the msBuild.BuildEngine is null.

MSBuild msBuild = new MSBuild ();
msBuild.BuildEngine.BuildProjectFile (csproj, new string[] { "Release" }, new Dictionary<string, string> (), new Dictionary<string, string> ());
msBuild.Execute ();

Upvotes: 1

Views: 636

Answers (1)

rene
rene

Reputation: 42414

You are instantiating the MSBuild task which is meant to be used from within a buildscript. In that context it gets the Engine from the host, most often the MSBuild executable.

You're looking for the Engine class that is found in the Microsoft.Build.BuildEngine namespace and sits in the assembly Microsoft.Build.Engine.dll .

The following Demo Console application shows how you can use that class. I've created a class MyBuild that has all the logic to create the Engine and build a projectfile.

class MyBuild
{
    string _proj;
    string _target;
    bool _result;

    public MyBuild(string proj, string target)
    {
        _proj = proj;
        _target= target;
    }

    public bool Result {get{return _result;}}

    public void Start() 
    {
        Engine engine = new Engine();
        engine.RegisterLogger(new ConsoleLogger());
        _result = engine.BuildProjectFile(_proj, _target);
    }
}

In the Main method we set things up. Notice that it also creates a Thread and sets its ApparatmentState to STA. In my testing I found no issues when not doing that but the warning was rather persistent so I assume there are scenario's where it might break if not run from such thread. Better safe then sorry.

using System;
using System.Threading;
using Microsoft.Build.BuildEngine;

public static void Main()
{
    string proj= @"yourprogram.csproj";
    string target = "Build";

    MyBuild mybuild = new MyBuild(proj, target);

    Thread t = new Thread(new ThreadStart(mybuild.Start));
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
    t.Join();

    if (mybuild.Result) 
    {
        Console.WriteLine("Success!");
    }
    else
    {
        Console.WriteLine("Failed!");
    }
}

To build above code you have to reference both the Engine.dll as the Framework.dll.

csc program.cs /r:C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Microsoft.Build.Engine.dll /r:C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Microsoft.Build.Framework.dll

Upvotes: 1

Related Questions