diff --git a/dir.props b/dir.props
index 5ec6bc45def..6513b304d0d 100644
--- a/dir.props
+++ b/dir.props
@@ -103,6 +103,7 @@
$(DefineConstants);FEATURE_APARTMENT_STATE
$(DefineConstants);FEATURE_APM
$(DefineConstants);FEATURE_APPDOMAIN
+ true
$(DefineConstants);FEATURE_APPDOMAIN_UNHANDLED_EXCEPTION
$(DefineConstants);FEATURE_ASSEMBLY_LOADFROM
$(DefineConstants);FEATURE_ASSEMBLY_LOCATION
@@ -122,10 +123,12 @@
$(DefineConstants);FEATURE_HANDLEREF
$(DefineConstants);FEATURE_MEMORYSTREAM_GETBUFFER
$(DefineConstants);FEATURE_OSVERSION
+ $(DefineConstants);FEATURE_PARALLEL_BUILD
$(DefineConstants);FEATURE_REFLECTION_EMIT_DEBUG_INFO
$(DefineConstants);FEATURE_REGISTRYHIVE_DYNDATA
$(DefineConstants);FEATURE_RESOURCE_EXPOSURE
$(DefineConstants);FEATURE_SECURITY_PERMISSIONS
+ $(DefineConstants);FEATURE_SECURITY_PRINCIPAL_WINDOWS
$(DefineConstants);FEATURE_SPECIAL_FOLDERS
true
$(DefineConstants);FEATURE_SYSTEM_CONFIGURATION
diff --git a/src/Shared/CommunicationsUtilities.cs b/src/Shared/CommunicationsUtilities.cs
index b1fb76c85e9..1f7985cdae1 100644
--- a/src/Shared/CommunicationsUtilities.cs
+++ b/src/Shared/CommunicationsUtilities.cs
@@ -310,6 +310,7 @@ internal static void SetEnvironment(IDictionary newEnvironment)
///
internal static long GenerateHostHandshakeFromBase(long baseHandshake, long clientHandshake)
{
+#if FEATURE_SECURITY_PRINCIPAL_WINDOWS
// If we are running in elevated privs, we will only accept a handshake from an elevated process as well.
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
@@ -328,6 +329,7 @@ internal static long GenerateHostHandshakeFromBase(long baseHandshake, long clie
baseHandshake = ~baseHandshake;
}
}
+#endif
// Mask out the first byte. That's because old
// builds used a single, non zero initial byte,
diff --git a/src/Shared/LogMessagePacketBase.cs b/src/Shared/LogMessagePacketBase.cs
index 0b6107eac40..7fa9f0b4c6e 100644
--- a/src/Shared/LogMessagePacketBase.cs
+++ b/src/Shared/LogMessagePacketBase.cs
@@ -14,7 +14,9 @@
using Microsoft.Build.Framework;
using Microsoft.Build.BackEnd;
+#if FEATURE_APPDOMAIN
using TaskEngineAssemblyResolver = Microsoft.Build.BackEnd.Logging.TaskEngineAssemblyResolver;
+#endif
namespace Microsoft.Build.Shared
{
@@ -136,10 +138,12 @@ private static int GetDefaultPacketVersion()
///
private static HashSet s_customEventsLoaded = new HashSet(StringComparer.OrdinalIgnoreCase);
+#if FEATURE_APPDOMAIN
///
/// The resolver used to load custom event types.
///
private static TaskEngineAssemblyResolver s_resolver;
+#endif
///
/// The object used to synchronize access to shared data.
@@ -389,12 +393,14 @@ internal void ReadFromStream(INodePacketTranslator translator)
}
}
+#if FEATURE_APPDOMAIN
if (resolveAssembly)
{
s_resolver = new TaskEngineAssemblyResolver();
s_resolver.InstallHandler();
s_resolver.Initialize(fileLocation);
}
+#endif
try
{
@@ -404,11 +410,13 @@ internal void ReadFromStream(INodePacketTranslator translator)
}
finally
{
+#if FEATURE_APPDOMAIN
if (resolveAssembly)
{
s_resolver.RemoveHandler();
s_resolver = null;
}
+#endif
}
}
diff --git a/src/Shared/TaskEngineAssemblyResolver.cs b/src/Shared/TaskEngineAssemblyResolver.cs
index 96c3871d960..2209b117bac 100644
--- a/src/Shared/TaskEngineAssemblyResolver.cs
+++ b/src/Shared/TaskEngineAssemblyResolver.cs
@@ -15,9 +15,7 @@ namespace Microsoft.Build.BackEnd.Logging
/// This is a helper class to install an AssemblyResolver event handler in whatever AppDomain this class is created in.
///
internal class TaskEngineAssemblyResolver
-#if FEATURE_APPDOMAIN
: MarshalByRefObject
-#endif
{
///
/// This public default constructor is needed so that instances of this class can be created by NDP.
@@ -114,7 +112,6 @@ internal Assembly ResolveAssembly(object sender, ResolveEventArgs args)
return null;
}
-#if FEATURE_APPDOMAIN
///
/// Overridden to give this class infinite lease time. Otherwise we end up with a limited
/// lease (5 minutes I think) and instances can expire if they take long time processing.
@@ -125,7 +122,6 @@ public override object InitializeLifetimeService()
// null means infinite lease time
return null;
}
-#endif
// path to the task assembly, but only if it's loaded using LoadFrom. If it's loaded with Load, this is null.
private string _taskAssemblyFile = null;
diff --git a/src/Shared/TaskHostConfiguration.cs b/src/Shared/TaskHostConfiguration.cs
index 1ab3294c8a7..0f5f93862c6 100644
--- a/src/Shared/TaskHostConfiguration.cs
+++ b/src/Shared/TaskHostConfiguration.cs
@@ -15,6 +15,7 @@
using System.Text;
using Microsoft.Build.Shared;
+using System.Reflection;
namespace Microsoft.Build.BackEnd
{
@@ -49,10 +50,12 @@ internal class TaskHostConfiguration : INodePacket
///
private CultureInfo _uiCulture = CultureInfo.CurrentUICulture;
+#if FEATURE_APPDOMAIN
///
/// The AppDomainSetup that we may want to use on AppDomainIsolated tasks.
///
private AppDomainSetup _appDomainSetup;
+#endif
///
/// Line number where the instance of this task is defined.
@@ -79,10 +82,14 @@ internal class TaskHostConfiguration : INodePacket
///
private string _taskName;
+#if FEATURE_ASSEMBLY_LOADFROM
///
/// Location of the assembly containing the task to be executed.
///
private string _taskLocation;
+#else
+ private AssemblyName _taskAssemblyName;
+#endif
///
/// The set of parameters to apply to the task prior to execution.
@@ -112,18 +119,26 @@ public TaskHostConfiguration
IDictionary buildProcessEnvironment,
CultureInfo culture,
CultureInfo uiCulture,
+#if FEATURE_APPDOMAIN
AppDomainSetup appDomainSetup,
+#endif
int lineNumberOfTask,
int columnNumberOfTask,
string projectFileOfTask,
bool continueOnError,
string taskName,
+#if FEATURE_ASSEMBLY_LOADFROM
string taskLocation,
+#else
+ AssemblyName taskAssemblyName,
+#endif
IDictionary taskParameters
)
{
ErrorUtilities.VerifyThrowInternalLength(taskName, "taskName");
+#if FEATURE_ASSEMBLY_LOADFROM
ErrorUtilities.VerifyThrowInternalLength(taskLocation, "taskLocation");
+#endif
_nodeId = nodeId;
_startupDirectory = startupDirectory;
@@ -140,13 +155,19 @@ public TaskHostConfiguration
_culture = culture;
_uiCulture = uiCulture;
+#if FEATURE_ASSEMBLY_LOADFROM
_appDomainSetup = appDomainSetup;
+#endif
_lineNumberOfTask = lineNumberOfTask;
_columnNumberOfTask = columnNumberOfTask;
_projectFileOfTask = projectFileOfTask;
_continueOnError = continueOnError;
_taskName = taskName;
+#if FEATURE_ASSEMBLY_LOADFROM
_taskLocation = taskLocation;
+#else
+ _taskAssemblyName = taskAssemblyName;
+#endif
if (taskParameters != null)
{
@@ -216,6 +237,7 @@ public CultureInfo UICulture
{ return _uiCulture; }
}
+#if FEATURE_APPDOMAIN
///
/// The AppDomain configuration bytes that we may want to use to initialize
/// AppDomainIsolated tasks.
@@ -226,6 +248,7 @@ public AppDomainSetup AppDomainSetup
get
{ return _appDomainSetup; }
}
+#endif
///
/// Line number where the instance of this task is defined.
@@ -277,6 +300,7 @@ public string TaskName
{ return _taskName; }
}
+#if FEATURE_ASSEMBLY_LOADFROM
///
/// Path to the assembly to load the task from.
///
@@ -286,6 +310,7 @@ public string TaskLocation
get
{ return _taskLocation; }
}
+#endif
///
/// Parameters to set on the instantiated task prior to execution.
@@ -325,7 +350,9 @@ public void Translate(INodePacketTranslator translator)
translator.Translate(ref _columnNumberOfTask);
translator.Translate(ref _projectFileOfTask);
translator.Translate(ref _taskName);
+#if FEATURE_ASSEMBLY_LOADFROM
translator.Translate(ref _taskLocation);
+#endif
translator.TranslateDictionary(ref _taskParameters, StringComparer.OrdinalIgnoreCase, TaskParameter.FactoryForDeserialization);
translator.Translate(ref _continueOnError);
}
diff --git a/src/Shared/TaskLoader.cs b/src/Shared/TaskLoader.cs
index 6a44898959f..6bcadac14af 100644
--- a/src/Shared/TaskLoader.cs
+++ b/src/Shared/TaskLoader.cs
@@ -46,15 +46,30 @@ internal static bool IsTaskClass(Type type, object unused)
///
/// Creates an ITask instance and returns it.
///
- internal static ITask CreateTask(LoadedType loadedType, string taskName, string taskLocation, int taskLine, int taskColumn, LogError logError, AppDomainSetup appDomainSetup, bool isOutOfProc, out AppDomain taskAppDomain)
+ internal static ITask CreateTask(LoadedType loadedType, string taskName, string taskLocation, int taskLine, int taskColumn, LogError logError
+#if FEATURE_APPDOMAIN
+ , AppDomainSetup appDomainSetup
+#endif
+ , bool isOutOfProc
+#if FEATURE_APPDOMAIN
+ , out AppDomain taskAppDomain
+#endif
+ )
{
+#if FEATURE_APPDOMAIN
bool separateAppDomain = loadedType.HasLoadInSeparateAppDomainAttribute();
+#else
+ bool separateAppDomain = false;
+#endif
s_resolverLoadedType = null;
+#if FEATURE_APPDOMAIN
taskAppDomain = null;
+#endif
ITask taskInstanceInOtherAppDomain = null;
try
{
+#if FEATURE_APPDOMAIN
if (separateAppDomain)
{
if (!loadedType.Type.GetTypeInfo().IsMarshalByRef)
@@ -109,12 +124,14 @@ internal static ITask CreateTask(LoadedType loadedType, string taskName, string
}
}
else
+#endif
{
// perf improvement for the same appdomain case - we already have the type object
// and don't want to go through reflection to recreate it from the name.
return (ITask)Activator.CreateInstance(loadedType.Type);
}
+#if FEATURE_APPDOMAIN
if (loadedType.Assembly.AssemblyFile != null)
{
taskInstanceInOtherAppDomain = (ITask)taskAppDomain.CreateInstanceFromAndUnwrap(loadedType.Assembly.AssemblyFile, loadedType.Type.FullName);
@@ -146,18 +163,22 @@ internal static ITask CreateTask(LoadedType loadedType, string taskName, string
}
return taskInstanceInOtherAppDomain;
+#endif
}
finally
{
+#if FEATURE_APPDOMAIN
// Don't leave appdomains open
if (taskAppDomain != null && taskInstanceInOtherAppDomain == null)
{
AppDomain.Unload(taskAppDomain);
RemoveAssemblyResolver();
}
+#endif
}
}
+#if FEATURE_APPDOMAIN
///
/// This is a resolver to help created AppDomains when they are unable to load an assembly into their domain we will help
/// them succeed by providing the already loaded one in the currentdomain so that they can derive AssemblyName info from it
@@ -187,5 +208,6 @@ internal static void RemoveAssemblyResolver()
s_resolverLoadedType = null;
}
}
+#endif
}
}
\ No newline at end of file
diff --git a/src/Shared/TaskLoggingHelper.cs b/src/Shared/TaskLoggingHelper.cs
index 62ebdf75d55..a0c958b5a89 100644
--- a/src/Shared/TaskLoggingHelper.cs
+++ b/src/Shared/TaskLoggingHelper.cs
@@ -7,8 +7,10 @@
using System.IO;
using System.Resources;
using System.Text;
+#if FEATURE_APPDOMAIN
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting;
+#endif
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;
@@ -64,12 +66,14 @@ public TaskLoggingHelper(IBuildEngine buildEngine, string taskName)
#region Properties
+#if FEATURE_APPDOMAIN
///
/// A client sponsor is a class
/// which will respond to a lease renewal request and will
/// increase the lease time allowing the object to stay in memory
///
private ClientSponsor _sponsor;
+#endif
// We have to pass an instance of ITask to BuildEngine, and since we call into the engine from this class we
// need to store the actual task instance.
diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs
index 8e95fa1d47b..a7a51e32ed4 100644
--- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs
+++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs
@@ -1626,8 +1626,10 @@ private NodeConfiguration GetNodeConfiguration()
(
-1, /* must be assigned by the NodeManager */
_buildParameters,
- remoteLoggers.ToArray(),
- AppDomain.CurrentDomain.SetupInformation
+ remoteLoggers.ToArray()
+#if FEATURE_APPDOMAIN
+ , AppDomain.CurrentDomain.SetupInformation
+#endif
);
}
diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs
index ca6ba797ded..4b137674259 100644
--- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs
+++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs
@@ -29,6 +29,7 @@
namespace Microsoft.Build.Execution
{
+ using System.Diagnostics;
using Utilities = Microsoft.Build.Internal.Utilities;
///
@@ -811,6 +812,7 @@ internal ProjectRootElementCache ProjectRootElementCache
set;
}
+#if FEATURE_APPDOMAIN
///
/// Information for configuring child AppDomains.
///
@@ -819,6 +821,7 @@ internal AppDomainSetup AppDomainSetup
get;
set;
}
+#endif
///
/// (for diagnostic use) Whether or not this is out of proc
@@ -1002,7 +1005,11 @@ private void FindMSBuildExe()
}
// Use the default location of the directory from which the engine was loaded.
+#if FEATURE_APPDOMAIN
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MSBuild.exe");
+#else
+ path = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
+#endif
if (path != null && CheckMSBuildExeExistsAt(path))
{
_nodeExeLocation = path;
@@ -1025,6 +1032,7 @@ private void FindMSBuildExe()
}
}
+#if FEATURE_APPDOMAIN
// Search in the location of any assemblies we have loaded.
foreach (System.Reflection.Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
@@ -1056,6 +1064,7 @@ private void FindMSBuildExe()
}
}
}
+#endif
// Search in the framework directory. Checks the COMPLUS_INSTALL_ROOT among other things.
path = FrameworkLocationHelper.PathToDotNetFrameworkV40;
diff --git a/src/XMakeBuildEngine/BackEnd/Components/BuildComponentFactoryCollection.cs b/src/XMakeBuildEngine/BackEnd/Components/BuildComponentFactoryCollection.cs
index 632714e8451..6a8e22307b7 100644
--- a/src/XMakeBuildEngine/BackEnd/Components/BuildComponentFactoryCollection.cs
+++ b/src/XMakeBuildEngine/BackEnd/Components/BuildComponentFactoryCollection.cs
@@ -66,8 +66,10 @@ public void RegisterDefaultFactories()
_componentEntriesByType[BuildComponentType.TaskHostNodeManager] = new BuildComponentEntry(BuildComponentType.TaskHostNodeManager, TaskHostNodeManager.CreateComponent, CreationPattern.Singleton);
_componentEntriesByType[BuildComponentType.InProcNodeProvider] = new BuildComponentEntry(BuildComponentType.InProcNodeProvider, NodeProviderInProc.CreateComponent, CreationPattern.Singleton);
+#if FEATURE_APPDOMAIN
_componentEntriesByType[BuildComponentType.OutOfProcNodeProvider] = new BuildComponentEntry(BuildComponentType.OutOfProcNodeProvider, NodeProviderOutOfProc.CreateComponent, CreationPattern.Singleton);
_componentEntriesByType[BuildComponentType.OutOfProcTaskHostNodeProvider] = new BuildComponentEntry(BuildComponentType.OutOfProcTaskHostNodeProvider, NodeProviderOutOfProcTaskHost.CreateComponent, CreationPattern.Singleton);
+#endif
// PropertyCache,
// RemoteNodeProvider,
diff --git a/src/XMakeBuildEngine/BackEnd/Components/Communications/LogMessagePacket.cs b/src/XMakeBuildEngine/BackEnd/Components/Communications/LogMessagePacket.cs
index d87faf474a0..07ae6abbbd4 100644
--- a/src/XMakeBuildEngine/BackEnd/Components/Communications/LogMessagePacket.cs
+++ b/src/XMakeBuildEngine/BackEnd/Components/Communications/LogMessagePacket.cs
@@ -14,7 +14,9 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;
using TaskItem = Microsoft.Build.Execution.ProjectItemInstance.TaskItem;
+#if FEATURE_APPDOMAIN
using TaskEngineAssemblyResolver = Microsoft.Build.BackEnd.Logging.TaskEngineAssemblyResolver;
+#endif
namespace Microsoft.Build.BackEnd
{
diff --git a/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskBuilder.cs b/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskBuilder.cs
index c0e6e89df5a..1a02d1701aa 100644
--- a/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskBuilder.cs
+++ b/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskBuilder.cs
@@ -303,7 +303,11 @@ private async Task ExecuteTask(TaskExecutionMode mode, Lookup lo
if (_taskNode != null)
{
taskHost = new TaskHost(_componentHost, _buildRequestEntry, _targetChildInstance.Location, _targetBuilderCallback);
- _taskExecutionHost.InitializeForTask(taskHost, _targetLoggingContext, _buildRequestEntry.RequestConfiguration.Project, _taskNode.Name, _taskNode.Location, _taskHostObject, _continueOnError != ContinueOnError.ErrorAndStop, taskHost.AppDomainSetup, taskHost.IsOutOfProc, _cancellationToken);
+ _taskExecutionHost.InitializeForTask(taskHost, _targetLoggingContext, _buildRequestEntry.RequestConfiguration.Project, _taskNode.Name, _taskNode.Location, _taskHostObject, _continueOnError != ContinueOnError.ErrorAndStop,
+#if FEATURE_APPDOMAIN
+ taskHost.AppDomainSetup,
+#endif
+ taskHost.IsOutOfProc, _cancellationToken);
}
List taskParameterValues = CreateListOfParameterValues();
diff --git a/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs b/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs
index bc46cfe3d4f..34acd2a405c 100644
--- a/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs
+++ b/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs
@@ -9,8 +9,10 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
+#if FEATURE_APPDOMAIN
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting;
+#endif
using System.Threading;
using System.Text;
using Microsoft.Build.Framework;
@@ -82,12 +84,14 @@ internal class TaskHost :
///
private object _callbackMonitor;
+#if FEATURE_APPDOMAIN
///
/// A client sponsor is a class
/// which will respond to a lease renewal request and will
/// increase the lease time allowing the object to stay in memory
///
private ClientSponsor _sponsor;
+#endif
///
/// Legacy continue on error value per batch exposed via IBuildEngine
@@ -214,6 +218,7 @@ internal TaskLoggingContext LoggingContext
{ _taskLoggingContext = value; }
}
+#if FEATURE_APPDOMAIN
///
/// For configuring child AppDomains.
///
@@ -224,6 +229,7 @@ internal AppDomainSetup AppDomainSetup
return _host.BuildParameters.AppDomainSetup;
}
}
+#endif
///
/// Whether or not this is out of proc.
diff --git a/src/XMakeBuildEngine/BackEnd/Node/InProcNode.cs b/src/XMakeBuildEngine/BackEnd/Node/InProcNode.cs
index 845a50361c3..145b3949dbc 100644
--- a/src/XMakeBuildEngine/BackEnd/Node/InProcNode.cs
+++ b/src/XMakeBuildEngine/BackEnd/Node/InProcNode.cs
@@ -513,8 +513,10 @@ private void HandleNodeConfiguration(NodeConfiguration configuration)
_componentHost.BuildParameters.NodeId = configuration.NodeId;
_shutdownException = null;
+#if FEATURE_APPDOMAIN
// And the AppDomainSetup
_componentHost.BuildParameters.AppDomainSetup = configuration.AppDomainSetup;
+#endif
// Declare in-proc
_componentHost.BuildParameters.IsOutOfProc = false;
diff --git a/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs b/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs
index 4abf13326d6..26b8d890600 100644
--- a/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs
+++ b/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs
@@ -34,10 +34,12 @@ internal class NodeConfiguration : INodePacket
///
private BuildParameters _buildParameters;
+#if FEATURE_APPDOMAIN
///
/// The app domain information needed for setting up AppDomain-isolated tasks.
///
private AppDomainSetup _appDomainSetup;
+#endif
///
/// The forwarding loggers to use.
@@ -55,14 +57,18 @@ public NodeConfiguration
(
int nodeId,
BuildParameters buildParameters,
- LoggerDescription[] forwardingLoggers,
- AppDomainSetup appDomainSetup
+ LoggerDescription[] forwardingLoggers
+#if FEATURE_APPDOMAIN
+ , AppDomainSetup appDomainSetup
+#endif
)
{
_nodeId = nodeId;
_buildParameters = buildParameters;
_forwardingLoggers = forwardingLoggers;
+#if FEATURE_APPDOMAIN
_appDomainSetup = appDomainSetup;
+#endif
}
///
@@ -106,6 +112,7 @@ public LoggerDescription[] LoggerDescriptions
{ return _forwardingLoggers; }
}
+#if FEATURE_APPDOMAIN
///
/// Retrieves the app domain setup information.
///
@@ -115,6 +122,7 @@ public AppDomainSetup AppDomainSetup
get
{ return _appDomainSetup; }
}
+#endif
#region INodePacket Members
@@ -162,7 +170,11 @@ internal static INodePacket FactoryForDeserialization(INodePacketTranslator tran
///
internal NodeConfiguration Clone()
{
- return new NodeConfiguration(_nodeId, _buildParameters, _forwardingLoggers, _appDomainSetup);
+ return new NodeConfiguration(_nodeId, _buildParameters, _forwardingLoggers
+#if FEATURE_APPDOMAIN
+ , _appDomainSetup
+#endif
+ );
}
}
}
diff --git a/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/AddInParts/ITaskExecutionHost.cs b/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/AddInParts/ITaskExecutionHost.cs
index 1193be9d244..0ae715f2007 100644
--- a/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/AddInParts/ITaskExecutionHost.cs
+++ b/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/AddInParts/ITaskExecutionHost.cs
@@ -67,7 +67,11 @@ bool LogTaskInputs
///
/// Initialize the host with the objects required to communicate with the host process.
///
- void InitializeForTask(IBuildEngine2 buildEngine, TargetLoggingContext loggingContext, ProjectInstance projectInstance, string taskName, ElementLocation taskLocation, ITaskHost taskHost, bool continueOnError, AppDomainSetup appDomainSetup, bool isOutOfProc, CancellationToken cancellationToken);
+ void InitializeForTask(IBuildEngine2 buildEngine, TargetLoggingContext loggingContext, ProjectInstance projectInstance, string taskName, ElementLocation taskLocation, ITaskHost taskHost, bool continueOnError,
+#if FEATURE_APPDOMAIN
+ AppDomainSetup appDomainSetup,
+#endif
+ bool isOutOfProc, CancellationToken cancellationToken);
///
/// Ask the task host to find its task in the registry and get it ready for initializing the batch
diff --git a/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/TaskExecutionHost.cs b/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/TaskExecutionHost.cs
index 051fe2f0d50..51950c7e666 100644
--- a/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/TaskExecutionHost.cs
+++ b/src/XMakeBuildEngine/BackEnd/TaskExecutionHost/TaskExecutionHost.cs
@@ -23,7 +23,9 @@
using Microsoft.Build.BackEnd.Logging;
using System.Globalization;
using System.Reflection;
+#if FEATURE_APPDOMAIN
using System.Runtime.Remoting;
+#endif
using TaskItem = Microsoft.Build.Execution.ProjectItemInstance.TaskItem;
@@ -52,10 +54,12 @@ internal class TaskExecutionHost : ITaskExecutionHost, IDisposable
///
private bool _logTaskInputs;
+#if FEATURE_APPDOMAIN
///
/// Resolver to assist in resolving types when a new appdomain is created
///
private TaskEngineAssemblyResolver _resolver;
+#endif
///
/// The interface used to call back into the build engine.
@@ -234,6 +238,7 @@ internal TaskFactoryWrapper _UNITTESTONLY_TaskFactoryWrapper
}
}
+#if FEATURE_APPDOMAIN
///
/// App domain configuration.
///
@@ -242,6 +247,7 @@ internal AppDomainSetup AppDomainSetup
get;
set;
}
+#endif
///
/// Whether or not this is out-of-proc.
@@ -266,7 +272,11 @@ public virtual void Dispose()
///
/// Initialize to run a specific task.
///
- void ITaskExecutionHost.InitializeForTask(IBuildEngine2 buildEngine, TargetLoggingContext loggingContext, ProjectInstance projectInstance, string taskName, ElementLocation taskLocation, ITaskHost taskHost, bool continueOnError, AppDomainSetup appDomainSetup, bool isOutOfProc, CancellationToken cancellationToken)
+ void ITaskExecutionHost.InitializeForTask(IBuildEngine2 buildEngine, TargetLoggingContext loggingContext, ProjectInstance projectInstance, string taskName, ElementLocation taskLocation, ITaskHost taskHost, bool continueOnError,
+#if FEATURE_APPDOMAIN
+ AppDomainSetup appDomainSetup,
+#endif
+ bool isOutOfProc, CancellationToken cancellationToken)
{
_buildEngine = buildEngine;
_projectInstance = projectInstance;
@@ -277,7 +287,9 @@ void ITaskExecutionHost.InitializeForTask(IBuildEngine2 buildEngine, TargetLoggi
_taskHost = taskHost;
_continueOnError = continueOnError;
_taskExecutionIdle.Set();
+#if FEATURE_APPDOMAIN
this.AppDomainSetup = appDomainSetup;
+#endif
this.IsOutOfProc = isOutOfProc;
}
@@ -332,6 +344,7 @@ bool ITaskExecutionHost.InitializeForBatch(TaskLoggingContext loggingContext, It
return false;
}
+#if FEATURE_APPDOMAIN
// If the task assembly is loaded into a separate AppDomain using LoadFrom, then we have a problem
// to solve - when the task class Type is marshalled back into our AppDomain, it's not just transferred
// here. Instead, NDP will try to Load (not LoadFrom!) the task assembly into our AppDomain, and since
@@ -343,6 +356,7 @@ bool ITaskExecutionHost.InitializeForBatch(TaskLoggingContext loggingContext, It
_resolver.Initialize(_taskFactoryWrapper.TaskFactoryLoadedType.Assembly.AssemblyFile);
_resolver.InstallHandler();
}
+#endif
// We instantiate a new task object for each batch
_taskInstance = InstantiateTask(taskIdentityParameters);
@@ -577,11 +591,13 @@ void ITaskExecutionHost.CleanupForBatch()
///
void ITaskExecutionHost.CleanupForTask()
{
+#if FEATURE_APPDOMAIN
if (_resolver != null)
{
_resolver.RemoveHandler();
_resolver = null;
}
+#endif
_taskFactoryWrapper = null;
@@ -996,7 +1012,11 @@ private ITask InstantiateTask(IDictionary taskIdentityParameters
AssemblyTaskFactory assemblyTaskFactory = _taskFactoryWrapper.TaskFactory as AssemblyTaskFactory;
if (assemblyTaskFactory != null)
{
- task = assemblyTaskFactory.CreateTaskInstance(_taskLocation, _taskLoggingContext, _buildComponentHost, taskIdentityParameters, this.AppDomainSetup, this.IsOutOfProc);
+ task = assemblyTaskFactory.CreateTaskInstance(_taskLocation, _taskLoggingContext, _buildComponentHost, taskIdentityParameters,
+#if FEATURE_APPDOMAIN
+ this.AppDomainSetup,
+#endif
+ this.IsOutOfProc);
}
else
{
diff --git a/src/XMakeBuildEngine/Debugger/DebuggerManager.cs b/src/XMakeBuildEngine/Debugger/DebuggerManager.cs
index 44ee479553a..636ffb5b93d 100644
--- a/src/XMakeBuildEngine/Debugger/DebuggerManager.cs
+++ b/src/XMakeBuildEngine/Debugger/DebuggerManager.cs
@@ -9,7 +9,9 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+#if FEATURE_DEBUGGER
using System.Diagnostics.SymbolStore;
+#endif
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
@@ -78,10 +80,12 @@ public static class DebuggerManager
///
private static MethodInfo s_islandCallback;
+#if FEATURE_DEBUGGER
///
/// Cached mapping of file path to symbol store documents
///
private static Dictionary s_sources = new Dictionary(StringComparer.OrdinalIgnoreCase);
+#endif
///
/// The single dynamic module used.
@@ -362,6 +366,7 @@ private static void CreateDynamicModule()
// of debuggable reflection-emit.
ErrorUtilities.VerifyThrow(s_dynamicModule == null, "Already emitted");
+#if FEATURE_DEBUGGER
// In a later release, this could be changed to use LightweightCodeGen (DynamicMethod instead of AssemblyBuilder);
// currently they don't support sequence points, so they can't be debugged in the normal way
AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("msbuild"), AssemblyBuilderAccess.Run);
@@ -382,6 +387,7 @@ private static void CreateDynamicModule()
s_dynamicModule = assembly.DefineDynamicModule(name, true /* track debug information */);
#else
s_dynamicModule = assembly.DefineDynamicModule(name);
+#endif
#endif
}
@@ -436,6 +442,7 @@ private static string CreateIsland(TypeBuilder typeBuilder, DebuggerState state)
// }
ILGenerator generator = method.GetILGenerator();
+#if FEATURE_DEBUGGER
ISymbolDocumentWriter source;
if (!s_sources.TryGetValue(state.Location.File, out source))
{
@@ -453,6 +460,7 @@ private static string CreateIsland(TypeBuilder typeBuilder, DebuggerState state)
generator.EmitCall(OpCodes.Call, s_islandCallback /* method */, null /* no opt params */);
generator.Emit(OpCodes.Ret); // Return from state
+#endif
return method.Name;
}
diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs
index d2ec682e843..33fd705c901 100644
--- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs
+++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs
@@ -14,8 +14,10 @@
using Microsoft.Build.Shared;
using Microsoft.Win32;
+#if FEATURE_APPDOMAIN
// Needed for DoesTaskHostExistForParameters
using NodeProviderOutOfProcTaskHost = Microsoft.Build.BackEnd.NodeProviderOutOfProcTaskHost;
+#endif
namespace Microsoft.Build.Evaluation
{
@@ -352,12 +354,14 @@ internal static bool DoesTaskHostExist(string runtime, string architecture)
parameters.Add(XMakeAttributes.architecture, architecture);
TaskHostContext desiredContext = CommunicationsUtilities.GetTaskHostContext(parameters);
+#if FEATURE_APPDOMAIN
string taskHostLocation = NodeProviderOutOfProcTaskHost.GetMSBuildLocationFromHostContext(desiredContext);
if (taskHostLocation != null && FileUtilities.FileExistsNoThrow(taskHostLocation))
{
return true;
}
+#endif
return false;
}
diff --git a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs
index baa24d08b5f..0fbfd48386d 100644
--- a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs
+++ b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs
@@ -20,7 +20,9 @@
using System.Globalization;
using Microsoft.Build.BackEnd;
+#if FEATURE_APPDOMAIN
using OutOfProcNode = Microsoft.Build.Execution.OutOfProcNode;
+#endif
namespace Microsoft.Build.Evaluation
{
@@ -610,7 +612,11 @@ private void DebugTraceCache(string message, string param1)
{
if (s_debugLogCacheActivity)
{
+#if FEATURE_APPDOMAIN
string prefix = OutOfProcNode.IsOutOfProcNode ? "C" : "P";
+#else
+ string prefix = "P";
+#endif
Trace.WriteLine(prefix + " " + Process.GetCurrentProcess().Id + " | " + message + param1);
}
}
diff --git a/src/XMakeBuildEngine/Instance/TaskFactories/AssemblyTaskFactory.cs b/src/XMakeBuildEngine/Instance/TaskFactories/AssemblyTaskFactory.cs
index 006836017d3..83af7738fcf 100644
--- a/src/XMakeBuildEngine/Instance/TaskFactories/AssemblyTaskFactory.cs
+++ b/src/XMakeBuildEngine/Instance/TaskFactories/AssemblyTaskFactory.cs
@@ -44,10 +44,12 @@ internal class AssemblyTaskFactory : ITaskFactory2
///
private LoadedType _loadedType;
+#if FEATURE_APPDOMAIN
///
/// A cache of tasks and the AppDomains they are loaded in.
///
private Dictionary _tasksAndAppDomains = new Dictionary();
+#endif
///
/// the set of parameters owned by this particular task host
@@ -238,8 +240,10 @@ public void CleanupTask(ITask task)
}
else
{
+#if FEATURE_APPDOMAIN
// It's really not necessary to do it for TaskHostTasks
TaskLoader.RemoveAssemblyResolver();
+#endif
}
}
@@ -320,7 +324,11 @@ string taskProjectFile
///
/// Create an instance of the wrapped ITask for a batch run of the task.
///
- internal ITask CreateTaskInstance(ElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary taskIdentityParameters, AppDomainSetup appDomainSetup, bool isOutOfProc)
+ internal ITask CreateTaskInstance(ElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary taskIdentityParameters,
+#if FEATURE_APPDOMAIN
+ AppDomainSetup appDomainSetup,
+#endif
+ bool isOutOfProc)
{
bool useTaskFactory = false;
IDictionary mergedParameters = null;
@@ -366,19 +374,35 @@ internal ITask CreateTaskInstance(ElementLocation taskLocation, TaskLoggingConte
mergedParameters[XMakeAttributes.architecture] = XMakeAttributes.GetCurrentMSBuildArchitecture();
}
- TaskHostTask task = new TaskHostTask(taskLocation, taskLoggingContext, buildComponentHost, mergedParameters, _loadedType, appDomainSetup);
+ TaskHostTask task = new TaskHostTask(taskLocation, taskLoggingContext, buildComponentHost, mergedParameters, _loadedType
+#if FEATURE_APPDOMAIN
+ , appDomainSetup
+#endif
+ );
return task;
}
else
{
+#if FEATURE_APPDOMAIN
AppDomain taskAppDomain = null;
+#endif
- ITask taskInstance = TaskLoader.CreateTask(_loadedType, _taskName, taskLocation.File, taskLocation.Line, taskLocation.Column, new TaskLoader.LogError(ErrorLoggingDelegate), appDomainSetup, isOutOfProc, out taskAppDomain);
+ ITask taskInstance = TaskLoader.CreateTask(_loadedType, _taskName, taskLocation.File, taskLocation.Line, taskLocation.Column, new TaskLoader.LogError(ErrorLoggingDelegate)
+#if FEATURE_APPDOMAIN
+ , appDomainSetup
+#endif
+ , isOutOfProc
+#if FEATURE_APPDOMAIN
+ , out taskAppDomain
+#endif
+ );
+#if FEATURE_APPDOMAIN
if (taskAppDomain != null)
{
_tasksAndAppDomains[taskInstance] = taskAppDomain;
}
+#endif
return taskInstance;
}
diff --git a/src/XMakeBuildEngine/Instance/TaskFactories/TaskHostTask.cs b/src/XMakeBuildEngine/Instance/TaskFactories/TaskHostTask.cs
index 7974281c1be..1d1b9b65db6 100644
--- a/src/XMakeBuildEngine/Instance/TaskFactories/TaskHostTask.cs
+++ b/src/XMakeBuildEngine/Instance/TaskFactories/TaskHostTask.cs
@@ -81,11 +81,13 @@ internal class TaskHostTask : IGeneratedTask, ICancelableTask, INodePacketFactor
///
private LoadedType _taskType;
+#if FEATURE_APPDOMAIN
///
/// The AppDomainSetup we'll want to apply to the AppDomain that we may
/// want to load the OOP task into.
///
private AppDomainSetup _appDomainSetup;
+#endif
///
/// The task host context of the task host we're launching -- used to
@@ -98,10 +100,12 @@ internal class TaskHostTask : IGeneratedTask, ICancelableTask, INodePacketFactor
///
private bool _connectedToTaskHost = false;
+#if FEATURE_APPDOMAIN
///
/// The provider for task host nodes.
///
private NodeProviderOutOfProcTaskHost _taskHostProvider;
+#endif
///
/// Lock object to serialize access to the task host.
@@ -127,7 +131,11 @@ internal class TaskHostTask : IGeneratedTask, ICancelableTask, INodePacketFactor
///
/// Constructor
///
- public TaskHostTask(IElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary taskHostParameters, LoadedType taskType, AppDomainSetup appDomainSetup)
+ public TaskHostTask(IElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary taskHostParameters, LoadedType taskType
+#if FEATURE_APPDOMAIN
+ , AppDomainSetup appDomainSetup
+#endif
+ )
{
ErrorUtilities.VerifyThrowInternalNull(taskType, "taskType");
@@ -135,7 +143,9 @@ public TaskHostTask(IElementLocation taskLocation, TaskLoggingContext taskLoggin
_taskLoggingContext = taskLoggingContext;
_buildComponentHost = buildComponentHost;
_taskType = taskType;
+#if FEATURE_APPDOMAIN
_appDomainSetup = appDomainSetup;
+#endif
_taskHostParameters = taskHostParameters;
_packetFactory = new NodePacketFactory();
@@ -223,6 +233,7 @@ public void Cancel()
{
if (!_taskCancelled)
{
+#if FEATURE_APPDOMAIN
lock (_taskHostLock)
{
if (_taskHostProvider != null && _connectedToTaskHost)
@@ -230,6 +241,7 @@ public void Cancel()
_taskHostProvider.SendData(_requiredContext, new TaskHostTaskCancelled());
}
}
+#endif
_taskCancelled = true;
}
@@ -248,8 +260,10 @@ public bool Execute()
// set up the node
lock (_taskHostLock)
{
+#if FEATURE_APPDOMAIN
_taskHostProvider = (NodeProviderOutOfProcTaskHost)_buildComponentHost.GetComponent(BuildComponentType.OutOfProcTaskHostNodeProvider);
ErrorUtilities.VerifyThrowInternalNull(_taskHostProvider, "taskHostProvider");
+#endif
}
TaskHostConfiguration hostConfiguration =
@@ -260,13 +274,19 @@ public bool Execute()
CommunicationsUtilities.GetEnvironmentVariables(),
_buildComponentHost.BuildParameters.Culture,
_buildComponentHost.BuildParameters.UICulture,
+#if FEATURE_APPDOMAIN
_appDomainSetup,
+#endif
BuildEngine.LineNumberOfTaskNode,
BuildEngine.ColumnNumberOfTaskNode,
BuildEngine.ProjectFileOfTaskNode,
BuildEngine.ContinueOnError,
_taskType.Type.FullName,
+#if FEATURE_ASSEMBLY_LOADFROM
_taskType.Type.GetTypeInfo().Assembly.Location,
+#else
+ _taskType.Type.GetTypeInfo().Assembly.GetName(),
+#endif
_setParameters
);
@@ -275,7 +295,9 @@ public bool Execute()
lock (_taskHostLock)
{
_requiredContext = CommunicationsUtilities.GetTaskHostContext(_taskHostParameters);
+#if FEATURE_APPDOMAIN
_connectedToTaskHost = _taskHostProvider.AcquireAndSetUpHost(_requiredContext, this, this, hostConfiguration);
+#endif
}
if (_connectedToTaskHost)
@@ -318,7 +340,9 @@ public bool Execute()
{
lock (_taskHostLock)
{
+#if FEATURE_APPDOMAIN
_taskHostProvider.DisconnectFromHost(_requiredContext);
+#endif
_connectedToTaskHost = false;
}
}
@@ -475,7 +499,13 @@ private void HandleTaskHostTaskComplete(TaskHostTaskComplete taskHostTaskComplet
else
{
exceptionMessage = "TaskInstantiationFailureError";
- exceptionMessageArgs = new string[] { _taskType.Type.Name, _taskType.Type.GetTypeInfo().Assembly.Location, String.Empty };
+ exceptionMessageArgs = new string[] { _taskType.Type.Name,
+#if FEATURE_ASSEMBLY_LOADFROM
+ _taskType.Type.GetTypeInfo().Assembly.Location,
+#else
+ _taskType.Type.GetTypeInfo().Assembly.FullName,
+#endif
+ String.Empty };
}
_taskLoggingContext.LogFatalError(new BuildEventFileInfo(_taskLocation), taskHostTaskComplete.TaskException, taskHostTaskComplete.TaskExceptionMessage, taskHostTaskComplete.TaskExceptionMessageArgs);
@@ -559,7 +589,11 @@ private void HandleLoggedMessage(LogMessagePacket logMessagePacket)
///
private void LogErrorUnableToCreateTaskHost(TaskHostContext requiredContext, string runtime, string architecture, NodeFailedToLaunchException e)
{
+#if FEATURE_APPDOMAIN
string msbuildLocation = NodeProviderOutOfProcTaskHost.GetMSBuildLocationFromHostContext(requiredContext);
+#else
+ string msbuildLocation = null;
+#endif
if (msbuildLocation == null)
{
diff --git a/src/XMakeBuildEngine/Instance/TaskRegistry.cs b/src/XMakeBuildEngine/Instance/TaskRegistry.cs
index ab3ebcfda64..11de9b3801e 100644
--- a/src/XMakeBuildEngine/Instance/TaskRegistry.cs
+++ b/src/XMakeBuildEngine/Instance/TaskRegistry.cs
@@ -20,7 +20,9 @@
using ILoggingService = Microsoft.Build.BackEnd.Logging.ILoggingService;
using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException;
+#if FEATURE_APPDOMAIN
using TaskEngineAssemblyResolver = Microsoft.Build.BackEnd.Logging.TaskEngineAssemblyResolver;
+#endif
using ProjectXmlUtilities = Microsoft.Build.Internal.ProjectXmlUtilities;
using TargetLoggingContext = Microsoft.Build.BackEnd.Logging.TargetLoggingContext;
using System.Collections.ObjectModel;
@@ -1233,10 +1235,13 @@ private bool GetTaskFactory(TargetLoggingContext targetLoggingContext, ElementLo
ITaskFactory factory = null;
LoadedType loadedType = null;
+
bool isAssemblyTaskFactory = String.Equals(TaskFactoryAttributeName, AssemblyTaskFactory, StringComparison.OrdinalIgnoreCase);
bool isTaskHostFactory = String.Equals(TaskFactoryAttributeName, TaskHostFactory, StringComparison.OrdinalIgnoreCase);
+#if FEATURE_APPDOMAIN
if (isAssemblyTaskFactory || isTaskHostFactory)
+#endif
{
bool explicitlyLaunchTaskHost =
isTaskHostFactory ||
@@ -1251,6 +1256,7 @@ private bool GetTaskFactory(TargetLoggingContext targetLoggingContext, ElementLo
loadedType = taskFactory.InitializeFactory(taskFactoryLoadInfo, RegisteredName, ParameterGroupAndTaskBody.UsingTaskParameters, ParameterGroupAndTaskBody.InlineTaskXmlBody, TaskFactoryParameters, explicitlyLaunchTaskHost, targetLoggingContext, elementLocation, taskProjectFile);
factory = taskFactory;
}
+#if FEATURE_APPDOMAIN
else
{
// We are not one of the default factories.
@@ -1351,9 +1357,7 @@ private bool GetTaskFactory(TargetLoggingContext targetLoggingContext, ElementLo
}
finally
{
-#if FEATURE_APPDOMAIN
taskFactoryLoggingHost.MarkAsInactive();
-#endif
}
if (!initialized)
@@ -1408,6 +1412,7 @@ private bool GetTaskFactory(TargetLoggingContext targetLoggingContext, ElementLo
}
}
}
+#endif
_taskFactoryWrapperInstance = new TaskFactoryWrapper(factory, loadedType, RegisteredName, TaskFactoryParameters);
}
diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj
index 112f56012f2..cf678447966 100644
--- a/src/XMakeBuildEngine/Microsoft.Build.csproj
+++ b/src/XMakeBuildEngine/Microsoft.Build.csproj
@@ -116,7 +116,7 @@
-
+
@@ -139,7 +139,7 @@
-
+
true
@@ -206,7 +206,7 @@
-
+
@@ -221,9 +221,9 @@
-
-
-
+
+
+
true
@@ -235,7 +235,7 @@
-
+