Search code examples
tfsbuildweb-config-transform

EntryPointNotFoundException when attempting to use TransformXml in custom build activity


In the process of setting up TFS 2013 to build and deploy sites and services to dev and test systems, I came across this StackOverflow answer for creating a custom build activity to transform Web.config files. I've added it to a build process template and TFS is calling it during its build/deploy process, though when transformation.Execute() is called, I receive

An unhandled exception of type 'System.EntryPointNotFoundException' occurred in Microsoft.Build.Utilities.v4.0.dll

Additional information: Entry point was not found.

I created a quick console app to call the custom activity directly and I get the same exception thrown on my local machine as well.

For reference, here's the custom build activity from the answer I linked above

/// <summary>
/// Transforms configuration files using TransformXml
/// </summary>
[BuildActivity(HostEnvironmentOption.All)]
public sealed class WebConfigTransform : CodeActivity
{
    #region Public Properties

    /// <summary>
    /// The binaries folder
    /// </summary>
    [RequiredArgument]
    public InArgument<string> BinariesLocation { get; set; }

    #endregion

    #region Overrides of CodeActivity

    /// <summary>
    /// When implemented in a derived class, performs the execution of the activity.
    /// </summary>
    /// <param name="context">The execution context under which the activity executes.</param>
    protected override void Execute(CodeActivityContext context)
    {
        var binariesFolder = context.GetValue(BinariesLocation);

        foreach (var sourceFolder in Directory.GetDirectories(Path.Combine(binariesFolder, "_PublishedWebsites")))
        {
            var sourceFile = Path.Combine(sourceFolder, "Web.config");
            if (File.Exists(sourceFile))
            {
                var filesToTransform = Directory.GetFiles(sourceFolder, "Web.*.config");


                foreach (var fileToTransform in filesToTransform)
                {

                    var tempSourceFile = Path.GetTempFileName();
                    var tempTransformFile = Path.GetTempFileName();

                    File.Copy(sourceFile, tempSourceFile, true);
                    File.Copy(fileToTransform, tempTransformFile, true);

                    var transformation = new TransformXml
                    {
                        BuildEngine = new BuildEngineStub(),
                        Source = tempSourceFile,
                        Transform = tempTransformFile,
                        Destination = fileToTransform
                    };

                    transformation.Execute();
                }
            }
        }
    }

    #endregion
}


public class BuildEngineStub : IBuildEngine
{
    #region IBuildEngine Members

    public bool BuildProjectFile(string projectFileName, string[] targetNames,
                                 IDictionary globalProperties,
                                 IDictionary targetOutputs)
    {
        throw new NotImplementedException();
    }

    public int ColumnNumberOfTaskNode
    {
        get { return 0; }
    }

    public bool ContinueOnError
    {
        get { return false; }
    }

    public int LineNumberOfTaskNode
    {
        get { return 0; }
    }

    public string ProjectFileOfTaskNode
    {
        get { return ""; }
    }

    public void LogCustomEvent(CustomBuildEventArgs e)
    {
        Console.WriteLine("Custom: {0}", e.Message);
    }

    public void LogErrorEvent(BuildErrorEventArgs e)
    {
        Console.WriteLine("Error: {0}", e.Message);
    }

    public void LogMessageEvent(BuildMessageEventArgs e)
    {
        Console.WriteLine("Message: {0}", e.Message);
    }

    public void LogWarningEvent(BuildWarningEventArgs e)
    {
        Console.WriteLine("Warning: {0}", e.Message);
    }

    #endregion
}

Solution

  • It seems that I had references to the incorrect versions of the dlls I needed; it compiled just fine but wouldn't run properly.

    Rather than search through C:\ to find the dlls necessary as suggested on another site, I found the four Microsoft assemblies I needed in Reference Manager > Assemblies > Framework

    Microsoft.Build.Framework

    Microsoft.Build.Utilities.v4.0

    Microsoft.TeamFoundation.Build.Client

    Microsoft.TeamFoundation.Build.Workflow

    This ended up fixing my problem, and the config file is now being transformed as needed