///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using JetBrains.Build.Omea.Util;
using Microsoft.Build.Framework;
namespace JetBrains.Build.Omea.Infra
{
///
/// The base task that locates the “resolved” part of the task being executed, loads it into another appdomain using the assembly resolved, and then executes in there.
///
public abstract class ProbingTask : TaskBase
{
#region Data
public static readonly string ResolvedPartAssemblyName = "JetBrains.Build.Omea.Resolved";
#endregion
#region Attributes
///
/// Gets or sets the list of assemblies that must be loaded for the Installer and such to function properly.
/// For example, for the installer to locate the ApplicationDescriptorAttribute, the DLL containing it must be already loaded.
/// The assemblies may be specified either as files or as assembly names, in which case their probing will be relied upon the resolver and the spec.
///
public ITaskItem[] LoadAssemblies
{
get
{
return Bag.Get(AttributeName.LoadAssemblies);
}
set
{
Bag.Set(AttributeName.LoadAssemblies, value);
}
}
#endregion
#region Implementation
///
/// Produces the list of probing locations for the .
///
protected string[] CollectProbingDirectories()
{
var directories = new List();
foreach(AttributeName attribute in ProbingDirectoryAttributes)
directories.Add(Bag.GetString(attribute));
return directories.ToArray();
}
///
/// Gets the list of attributes that must contain the probing directories.
///
protected virtual ICollection ProbingDirectoryAttributes
{
get
{
return new AttributeName[] {};
}
}
#endregion
#region Overrides
///
///When overridden in a derived class, executes the task.
///
///
///
///true if the task successfully executed; otherwise, false.
///
///
protected override sealed void ExecuteTask()
{
// Create a new appdomain
var appdomainparams = new AppDomainSetup();
appdomainparams.ApplicationBase = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath);
AppDomain appdomain = AppDomain.CreateDomain(ResolvedPartAssemblyName, AppDomain.CurrentDomain.Evidence, appdomainparams);
// Add service parameters to the bag
Bag.Set(AttributeName.AfxProbingDirectories, CollectProbingDirectories());
Bag.Set(AttributeName.AfxUnresolvedTaskName, GetType().Name);
Bag.Set(AttributeName.AfxLog, Log);
// Use the appdomain
try
{
appdomain.DoCallBack(new ProbingTaskResolved(Bag).Execute);
}
finally
{
// Dispose of the appdomain
AppDomain.Unload(appdomain);
}
// Check for execution exceptions, rethrow as needed
if(Bag.Contains(AttributeName.AfxException))
throw Bag.Get(AttributeName.AfxException);
}
#endregion
}
}