/// <summary>
        /// We just need the loaded type information because the task factory which is not instance specific should 
        /// already have loaded the assembly and got the information.
        /// </summary>
        public AssemblyTaskFactoryInstance(string taskName, LoadedType loadedType)
        {
            ErrorUtilities.VerifyThrowArgumentLength(taskName, "taskName");
            ErrorUtilities.VerifyThrowArgumentNull(loadedType, "loadedType");

            this.taskName = taskName;
            this.loadedType = loadedType;
        }
예제 #2
0
 /// <summary>
 /// Check if we added a resolver and remove it
 /// </summary>
 internal static void RemoveAssemblyResolver()
 {
     if (s_resolverLoadedType != null)
     {
         AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolver;
         s_resolverLoadedType = null;
     }
 }
예제 #3
0
 /// <summary>
 /// Creates an instance of this class for the given type.
 /// </summary>
 internal TaskFactoryWrapper(ITaskFactory taskFactory, LoadedType taskFactoryLoadInfo, string taskName, IDictionary<string, string> factoryIdentityParameters)
 {
     ErrorUtilities.VerifyThrowArgumentNull(taskFactory, "taskFactory");
     ErrorUtilities.VerifyThrowArgumentLength(taskName, "taskName");
     _taskFactory = taskFactory;
     _taskName = taskName;
     TaskFactoryLoadedType = taskFactoryLoadInfo;
     _factoryIdentityParameters = factoryIdentityParameters;
 }
 /// <summary>
 /// Abstract out the creation of the new AssemblyTaskFactory with default task, and 
 /// with some basic validation.
 /// </summary>
 private void SetupTaskFactory(IDictionary<string, string> factoryParameters, bool explicitlyLaunchTaskHost)
 {
     _taskFactory = new AssemblyTaskFactory();
     _loadInfo = AssemblyLoadInfo.Create(null, Assembly.GetAssembly(typeof(TaskToTestFactories)).Location);
     _loadedType = _taskFactory.InitializeFactory(_loadInfo, "TaskToTestFactories", new Dictionary<string, TaskPropertyInfo>(), string.Empty, factoryParameters, explicitlyLaunchTaskHost, null, ElementLocation.Create("NONE"), String.Empty);
     Assert.True(_loadedType.Assembly.Equals(_loadInfo)); // "Expected the AssemblyLoadInfo to be equal"
 }
        public void VerifyGetTaskParameters()
        {
            TaskPropertyInfo[] propertyInfos = _taskFactory.GetTaskParameters();
            LoadedType comparisonType = new LoadedType(typeof(TaskToTestFactories), _loadInfo);
            PropertyInfo[] comparisonInfo = comparisonType.Type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            Assert.Equal(comparisonInfo.Length, propertyInfos.Length);

            bool foundExpectedParameter = false;
            bool foundNotExpectedParameter = false;

            for (int i = 0; i < propertyInfos.Length; i++)
            {
                if (propertyInfos[i].Name.Equals("ExpectedParameter", StringComparison.OrdinalIgnoreCase))
                {
                    foundExpectedParameter = true;
                }

                if (propertyInfos[i].Name.Equals("NotExpectedParameter", StringComparison.OrdinalIgnoreCase))
                {
                    foundNotExpectedParameter = true;
                }
            }

            Assert.True(foundExpectedParameter);
            Assert.False(foundNotExpectedParameter);
        }
예제 #6
0
        /// <summary>
        /// Initialize the factory from the task registry
        /// </summary>
        internal LoadedType InitializeFactory
            (
                AssemblyLoadInfo loadInfo,
                string taskName,
                IDictionary<string, TaskPropertyInfo> taskParameters,
                string taskElementContents,
                IDictionary<string, string> taskFactoryIdentityParameters,
                bool taskHostFactoryExplicitlyRequested,
                TargetLoggingContext targetLoggingContext,
                ElementLocation elementLocation,
                string taskProjectFile
            )
        {
            ErrorUtilities.VerifyThrowArgumentNull(loadInfo, "loadInfo");
            VerifyThrowIdentityParametersValid(taskFactoryIdentityParameters, elementLocation, taskName, "Runtime", "Architecture");

            if (taskFactoryIdentityParameters != null)
            {
                _factoryIdentityParameters = new Dictionary<string, string>(taskFactoryIdentityParameters, StringComparer.OrdinalIgnoreCase);
            }

            _taskHostFactoryExplicitlyRequested = taskHostFactoryExplicitlyRequested;

            try
            {
                ErrorUtilities.VerifyThrowArgumentLength(taskName, "taskName");
                _taskName = taskName;
                _loadedType = _typeLoader.Load(taskName, loadInfo);
                ProjectErrorUtilities.VerifyThrowInvalidProject(_loadedType != null, elementLocation, "TaskLoadFailure", taskName, loadInfo.AssemblyLocation, String.Empty);
            }
            catch (TargetInvocationException e)
            {
                // Exception thrown by the called code itself
                // Log the stack, so the task vendor can fix their code
                ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, "TaskLoadFailure", taskName, loadInfo.AssemblyLocation, Environment.NewLine + e.InnerException.ToString());
            }
            catch (ReflectionTypeLoadException e)
            {
                // ReflectionTypeLoadException.LoaderExceptions may contain nulls
                foreach (Exception exception in e.LoaderExceptions)
                {
                    if (exception != null)
                    {
                        targetLoggingContext.LogError(new BuildEventFileInfo(taskProjectFile), "TaskLoadFailure", taskName, loadInfo.AssemblyLocation, exception.Message);
                    }
                }

                ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, "TaskLoadFailure", taskName, loadInfo.AssemblyLocation, e.Message);
            }
            catch (ArgumentNullException e)
            {
                // taskName may be null
                ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, "TaskLoadFailure", taskName, loadInfo.AssemblyLocation, e.Message);
            }
            catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception.
            {
                if (ExceptionHandling.NotExpectedReflectionException(e))
                {
                    throw;
                }

                ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, "TaskLoadFailure", taskName, loadInfo.AssemblyLocation, e.Message);
            }

            return _loadedType;
        }
예제 #7
0
        /// <summary>
        /// Creates an ITask instance and returns it.
        /// </summary>
        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();
            s_resolverLoadedType = null;
            taskAppDomain        = null;
            ITask taskInstanceInOtherAppDomain = null;
#endif

            try
            {
#if FEATURE_APPDOMAIN
                if (separateAppDomain)
                {
                    if (!loadedType.Type.GetTypeInfo().IsMarshalByRef)
                    {
                        logError
                        (
                            taskLocation,
                            taskLine,
                            taskColumn,
                            "TaskNotMarshalByRef",
                            taskName
                        );

                        return(null);
                    }
                    else
                    {
                        // Our task depend on this name to be precisely that, so if you change it make sure
                        // you also change the checks in the tasks run in separate AppDomains. Better yet, just don't change it.

                        // Make sure we copy the appdomain configuration and send it to the appdomain we create so that if the creator of the current appdomain
                        // has done the binding redirection in code, that we will get those settings as well.
                        AppDomainSetup appDomainInfo = new AppDomainSetup();

                        // Get the current app domain setup settings
                        byte[] currentAppdomainBytes = appDomainSetup.GetConfigurationBytes();

                        // Apply the appdomain settings to the new appdomain before creating it
                        appDomainInfo.SetConfigurationBytes(currentAppdomainBytes);

                        if (BuildEnvironmentHelper.Instance.RunningTests)
                        {
                            // Prevent the new app domain from looking in the VS test runner location. If this
                            // is not done, we will not be able to find Microsoft.Build.* assemblies.
                            appDomainInfo.ApplicationBase   = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory;
                            appDomainInfo.ConfigurationFile = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile;
                        }
                        else
                        {
                            // Set the taskAppDomain's BaseDirectory to the one containing the msbuild assemblies
                            // This host assembly might not be MSBuild.exe and so could be in a different location,
                            // so, look for a type in Microsoft.Build.dll
                            appDomainInfo.ApplicationBase = Path.GetDirectoryName(typeof(Microsoft.Build.Execution.ProjectInstance).Assembly.Location);
                        }

                        AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
                        s_resolverLoadedType = loadedType;

                        taskAppDomain = AppDomain.CreateDomain(isOutOfProc ? "taskAppDomain (out-of-proc)" : "taskAppDomain (in-proc)", null, appDomainInfo);

                        if (loadedType.LoadedAssembly != null)
                        {
                            taskAppDomain.Load(loadedType.LoadedAssembly.GetName());
                        }

#if FEATURE_APPDOMAIN_UNHANDLED_EXCEPTION
                        // Hook up last minute dumping of any exceptions
                        taskAppDomain.UnhandledException += new UnhandledExceptionEventHandler(ExceptionHandling.UnhandledExceptionHandler);
#endif
                    }
                }
                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);

                    // this will force evaluation of the task class type and try to load the task assembly
                    Type taskType = taskInstanceInOtherAppDomain.GetType();

                    // If the types don't match, we have a problem. It means that our AppDomain was able to load
                    // a task assembly using Load, and loaded a different one. I don't see any other choice than
                    // to fail here.
                    if (taskType != loadedType.Type)
                    {
                        logError
                        (
                            taskLocation,
                            taskLine,
                            taskColumn,
                            "ConflictingTaskAssembly",
                            loadedType.Assembly.AssemblyFile,
                            loadedType.Type.GetTypeInfo().Assembly.Location
                        );

                        taskInstanceInOtherAppDomain = null;
                    }
                }
                else
                {
                    taskInstanceInOtherAppDomain = (ITask)taskAppDomain.CreateInstanceAndUnwrap(loadedType.Type.GetTypeInfo().Assembly.FullName, loadedType.Type.FullName);
                }

                return(taskInstanceInOtherAppDomain);
#endif
            }
            finally
            {
#if FEATURE_APPDOMAIN
                // Don't leave appdomains open
                if (taskAppDomain != null && taskInstanceInOtherAppDomain == null)
                {
                    AppDomain.Unload(taskAppDomain);
                    RemoveAssemblyResolver();
                }
#endif
            }
        }
예제 #8
0
        /// <summary>
        /// Initialize the host object
        /// </summary>
        /// <param name="throwOnExecute">Should the task throw when executed</param>
        private void InitializeHost(bool throwOnExecute)
        {
            _loggingService = LoggingService.CreateLoggingService(LoggerMode.Synchronous, 1) as ILoggingService;
            _logger = new MockLogger();
            _loggingService.RegisterLogger(_logger);
            _host = new TaskExecutionHost();
            TargetLoggingContext tlc = new TargetLoggingContext(_loggingService, new BuildEventContext(1, 1, BuildEventContext.InvalidProjectContextId, 1));

            // Set up a temporary project and add some items to it.
            ProjectInstance project = CreateTestProject();

            TypeLoader typeLoader = new TypeLoader(new TypeFilter(IsTaskFactoryClass));
            AssemblyLoadInfo loadInfo = AssemblyLoadInfo.Create(Assembly.GetAssembly(typeof(TaskBuilderTestTask.TaskBuilderTestTaskFactory)).FullName, null);
            LoadedType loadedType = new LoadedType(typeof(TaskBuilderTestTask.TaskBuilderTestTaskFactory), loadInfo);

            TaskBuilderTestTask.TaskBuilderTestTaskFactory taskFactory = new TaskBuilderTestTask.TaskBuilderTestTaskFactory();
            taskFactory.ThrowOnExecute = throwOnExecute;
            string taskName = "TaskBuilderTestTask";
            (_host as TaskExecutionHost)._UNITTESTONLY_TaskFactoryWrapper = new TaskFactoryWrapper(taskFactory, loadedType, taskName, null);
            _host.InitializeForTask
                (
                this,
                tlc,
                project,
                taskName,
                ElementLocation.Create("none", 1, 1),
                this,
                false,
                null,
                false,
                CancellationToken.None
                );

            ProjectTaskInstance taskInstance = project.Targets["foo"].Tasks.First();
            TaskLoggingContext talc = tlc.LogTaskBatchStarted(".", taskInstance);

            ItemDictionary<ProjectItemInstance> itemsByName = new ItemDictionary<ProjectItemInstance>();

            ProjectItemInstance item = new ProjectItemInstance(project, "ItemListContainingOneItem", "a.cs", ".");
            item.SetMetadata("Culture", "fr-fr");
            itemsByName.Add(item);
            _oneItem = new ITaskItem[] { new TaskItem(item) };

            item = new ProjectItemInstance(project, "ItemListContainingTwoItems", "b.cs", ".");
            ProjectItemInstance item2 = new ProjectItemInstance(project, "ItemListContainingTwoItems", "c.cs", ".");
            item.SetMetadata("HintPath", "c:\\foo");
            item2.SetMetadata("HintPath", "c:\\bar");
            itemsByName.Add(item);
            itemsByName.Add(item2);
            _twoItems = new ITaskItem[] { new TaskItem(item), new TaskItem(item2) };

            _bucket = new ItemBucket(new string[0], new Dictionary<string, string>(), new Lookup(itemsByName, new PropertyDictionary<ProjectPropertyInstance>(), null), 0);
            _host.FindTask(null);
            _host.InitializeForBatch(talc, _bucket, null);
            _parametersSetOnTask = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            _outputsReadFromTask = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        }
        /// <summary>
        /// Do the work of actually instantiating and running the task. 
        /// </summary>
        private OutOfProcTaskHostTaskResult InstantiateAndExecuteTask
            (
                IBuildEngine oopTaskHostNode,
                LoadedType taskType,
                string taskName,
                string taskLocation,
                string taskFile,
                int taskLine,
                int taskColumn,
                AppDomainSetup appDomainSetup,
                IDictionary<string, TaskParameter> taskParams
            )
        {
            _taskAppDomain = null;
            _wrappedTask = null;

            try
            {
                _wrappedTask = TaskLoader.CreateTask(taskType, taskName, taskFile, taskLine, taskColumn, new TaskLoader.LogError(LogErrorDelegate), appDomainSetup, true /* always out of proc */, out _taskAppDomain);
                Type wrappedTaskType = _wrappedTask.GetType();

                _wrappedTask.BuildEngine = oopTaskHostNode;
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                {
                    throw;
                }

                Exception exceptionToReturn = e;

                // If it's a TargetInvocationException, we only care about the contents of the inner exception, 
                // so just save that instead. 
                if (e is TargetInvocationException)
                {
                    exceptionToReturn = e.InnerException;
                }

                return new OutOfProcTaskHostTaskResult
                (
                    TaskCompleteType.CrashedDuringInitialization,
                    exceptionToReturn,
                    "TaskInstantiationFailureError",
                    new string[] { taskName, taskLocation, String.Empty }
                );
            }

            foreach (KeyValuePair<string, TaskParameter> param in taskParams)
            {
                try
                {
                    PropertyInfo paramInfo = _wrappedTask.GetType().GetProperty(param.Key, BindingFlags.Instance | BindingFlags.Public);
                    paramInfo.SetValue(_wrappedTask, (param.Value == null ? null : param.Value.WrappedParameter), null);
                }
                catch (Exception e)
                {
                    if (ExceptionHandling.IsCriticalException(e))
                    {
                        throw;
                    }

                    Exception exceptionToReturn = e;

                    // If it's a TargetInvocationException, we only care about the contents of the inner exception, 
                    // so just save that instead. 
                    if (e is TargetInvocationException)
                    {
                        exceptionToReturn = e.InnerException;
                    }

                    return new OutOfProcTaskHostTaskResult
                                    (
                                        TaskCompleteType.CrashedDuringInitialization,
                                        exceptionToReturn,
                                        "InvalidTaskAttributeError",
                                        new string[] { param.Key, param.Value.ToString(), taskName }
                                    );
                }
            }

            bool success = false;
            try
            {
                if (CancelPending)
                {
                    return new OutOfProcTaskHostTaskResult(TaskCompleteType.Failure);
                }

                // If it didn't crash and return before now, we're clear to go ahead and execute here. 
                success = _wrappedTask.Execute();
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                {
                    throw;
                }

                return new OutOfProcTaskHostTaskResult(TaskCompleteType.CrashedDuringExecution, e);
            }

            PropertyInfo[] finalPropertyValues = _wrappedTask.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            IDictionary<string, Object> finalParameterValues = new Dictionary<string, Object>(StringComparer.OrdinalIgnoreCase);
            foreach (PropertyInfo value in finalPropertyValues)
            {
                // only record outputs
                if (value.GetCustomAttributes(typeof(OutputAttribute), true).Length > 0)
                {
                    try
                    {
                        finalParameterValues[value.Name] = value.GetValue(_wrappedTask, null);
                    }
                    catch (Exception e)
                    {
                        if (ExceptionHandling.IsCriticalException(e))
                        {
                            throw;
                        }

                        // If it's not a critical exception, we assume there's some sort of problem in the parameter getter -- 
                        // so save the exception, and we'll re-throw once we're back on the main node side of the 
                        // communications pipe.  
                        finalParameterValues[value.Name] = e;
                    }
                }
            }

            return new OutOfProcTaskHostTaskResult(success ? TaskCompleteType.Success : TaskCompleteType.Failure, finalParameterValues);
        }
 public void TearDownAttribute()
 {
     _taskFactory = null;
     _loadInfo = null;
     _loadedType = null;
 }
        /// <summary>
        /// Execute a task on the STA thread. 
        /// </summary>
        /// <comment>
        /// STA thread launching code lifted from XMakeBuildEngine\BackEnd\Components\RequestBuilder\TaskBuilder.cs, ExecuteTaskInSTAThread method.  
        /// Any bug fixes made to this code, please ensure that you also fix that code.  
        /// </comment>
        private OutOfProcTaskHostTaskResult InstantiateAndExecuteTaskInSTAThread
            (
                IBuildEngine oopTaskHostNode,
                LoadedType taskType,
                string taskName,
                string taskLocation,
                string taskFile,
                int taskLine,
                int taskColumn,
                AppDomainSetup appDomainSetup,
                IDictionary<string, TaskParameter> taskParams
            )
        {
            ManualResetEvent taskRunnerFinished = new ManualResetEvent(false);
            OutOfProcTaskHostTaskResult taskResult = null;
            Exception exceptionFromExecution = null;

            try
            {
                ThreadStart taskRunnerDelegate = delegate ()
                {
                    try
                    {
                        taskResult = InstantiateAndExecuteTask
                                            (
                                                oopTaskHostNode,
                                                taskType,
                                                taskName,
                                                taskLocation,
                                                taskFile,
                                                taskLine,
                                                taskColumn,
                                                appDomainSetup,
                                                taskParams
                                            );
                    }
                    catch (Exception e)
                    {
                        if (ExceptionHandling.IsCriticalException(e))
                        {
                            throw;
                        }

                        exceptionFromExecution = e;
                    }
                    finally
                    {
                        taskRunnerFinished.Set();
                    }
                };

                Thread staThread = new Thread(taskRunnerDelegate);
                staThread.SetApartmentState(ApartmentState.STA);
                staThread.Name = "MSBuild STA task runner thread";
                staThread.CurrentCulture = Thread.CurrentThread.CurrentCulture;
                staThread.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
                staThread.Start();

                // TODO: Why not just Join on the thread???
                taskRunnerFinished.WaitOne();
            }
            finally
            {
                taskRunnerFinished.Close();
                taskRunnerFinished = null;
            }

            if (exceptionFromExecution != null)
            {
                // Unfortunately this will reset the callstack
                throw exceptionFromExecution;
            }

            return taskResult;
        }
예제 #12
0
        /// <summary>
        /// Creates an ITask instance and returns it.  
        /// </summary>
        internal static ITask CreateTask(LoadedType loadedType, string taskName, string taskLocation, int taskLine, int taskColumn, LogError logError, AppDomainSetup appDomainSetup, bool isOutOfProc, out AppDomain taskAppDomain)
        {
            bool separateAppDomain = loadedType.HasLoadInSeparateAppDomainAttribute();
            s_resolverLoadedType = null;
            taskAppDomain = null;
            ITask taskInstanceInOtherAppDomain = null;

            try
            {
                if (separateAppDomain)
                {
                    if (!loadedType.Type.IsMarshalByRef)
                    {
                        logError
                        (
                            taskLocation,
                            taskLine,
                            taskColumn,
                            "TaskNotMarshalByRef",
                            taskName
                         );

                        return null;
                    }
                    else
                    {
                        // Our task depend on this name to be precisely that, so if you change it make sure
                        // you also change the checks in the tasks run in separate AppDomains. Better yet, just don't change it.

                        // Make sure we copy the appdomain configuration and send it to the appdomain we create so that if the creator of the current appdomain
                        // has done the binding redirection in code, that we will get those settings as well.
                        AppDomainSetup appDomainInfo = new AppDomainSetup();

                        // Get the current app domain setup settings
                        byte[] currentAppdomainBytes = appDomainSetup.GetConfigurationBytes();

                        // Apply the appdomain settings to the new appdomain before creating it
                        appDomainInfo.SetConfigurationBytes(currentAppdomainBytes);

                        AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
                        s_resolverLoadedType = loadedType;

                        taskAppDomain = AppDomain.CreateDomain(isOutOfProc ? "taskAppDomain (out-of-proc)" : "taskAppDomain (in-proc)", null, appDomainInfo);

                        if (loadedType.LoadedAssembly != null)
                        {
                            taskAppDomain.Load(loadedType.LoadedAssembly.GetName());
                        }

                        // Hook up last minute dumping of any exceptions 
                        taskAppDomain.UnhandledException += new UnhandledExceptionEventHandler(ExceptionHandling.UnhandledExceptionHandler);
                    }
                }
                else
                {
                    // 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 (loadedType.Assembly.AssemblyFile != null)
                {
                    taskInstanceInOtherAppDomain = (ITask)taskAppDomain.CreateInstanceFromAndUnwrap(loadedType.Assembly.AssemblyFile, loadedType.Type.FullName);

                    // this will force evaluation of the task class type and try to load the task assembly
                    Type taskType = taskInstanceInOtherAppDomain.GetType();

                    // If the types don't match, we have a problem. It means that our AppDomain was able to load
                    // a task assembly using Load, and loaded a different one. I don't see any other choice than
                    // to fail here.
                    if (taskType != loadedType.Type)
                    {
                        logError
                        (
                        taskLocation,
                        taskLine,
                        taskColumn,
                        "ConflictingTaskAssembly",
                        loadedType.Assembly.AssemblyFile,
                        loadedType.Type.Assembly.Location
                        );

                        taskInstanceInOtherAppDomain = null;
                    }
                }
                else
                {
                    taskInstanceInOtherAppDomain = (ITask)taskAppDomain.CreateInstanceAndUnwrap(loadedType.Type.Assembly.FullName, loadedType.Type.FullName);
                }

                return taskInstanceInOtherAppDomain;
            }
            finally
            {
                // Don't leave appdomains open
                if (taskAppDomain != null && taskInstanceInOtherAppDomain == null)
                {
                    AppDomain.Unload(taskAppDomain);
                    RemoveAssemblyResolver();
                }
            }
        }
예제 #13
0
 /// <summary>
 /// Check if we added a resolver and remove it
 /// </summary>
 internal static void RemoveAssemblyResolver()
 {
     if (s_resolverLoadedType != null)
     {
         AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolver;
         s_resolverLoadedType = null;
     }
 }
예제 #14
0
        /// <summary>
        /// Constructor
        /// </summary>
        public TaskHostTask(IElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary<string, string> taskHostParameters, LoadedType taskType, AppDomainSetup appDomainSetup)
        {
            ErrorUtilities.VerifyThrowInternalNull(taskType, "taskType");

            _taskLocation = taskLocation;
            _taskLoggingContext = taskLoggingContext;
            _buildComponentHost = buildComponentHost;
            _taskType = taskType;
            _appDomainSetup = appDomainSetup;
            _taskHostParameters = taskHostParameters;

            _packetFactory = new NodePacketFactory();

            (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, this);
            (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.TaskHostTaskComplete, TaskHostTaskComplete.FactoryForDeserialization, this);
            (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeShutdown, NodeShutdown.FactoryForDeserialization, this);

            _packetReceivedEvent = new AutoResetEvent(false);
            _receivedPackets = new Queue<INodePacket>();
            _taskHostLock = new Object();

            _setParameters = new Dictionary<string, object>();
        }
예제 #15
0
        /// <summary>
        /// Creates an ITask instance and returns it.
        /// </summary>
        internal static ITask CreateTask(LoadedType loadedType, string taskName, string taskLocation, int taskLine, int taskColumn, LogError logError, AppDomainSetup appDomainSetup, bool isOutOfProc, out AppDomain taskAppDomain)
        {
            bool separateAppDomain = loadedType.HasLoadInSeparateAppDomainAttribute();

            s_resolverLoadedType = null;
            taskAppDomain        = null;
            ITask taskInstanceInOtherAppDomain = null;

            try
            {
                if (separateAppDomain)
                {
                    if (!loadedType.Type.IsMarshalByRef)
                    {
                        logError
                        (
                            taskLocation,
                            taskLine,
                            taskColumn,
                            "TaskNotMarshalByRef",
                            taskName
                        );

                        return(null);
                    }
                    else
                    {
                        // Our task depend on this name to be precisely that, so if you change it make sure
                        // you also change the checks in the tasks run in separate AppDomains. Better yet, just don't change it.

                        // Make sure we copy the appdomain configuration and send it to the appdomain we create so that if the creator of the current appdomain
                        // has done the binding redirection in code, that we will get those settings as well.
                        AppDomainSetup appDomainInfo = new AppDomainSetup();

                        // Get the current app domain setup settings
                        byte[] currentAppdomainBytes = appDomainSetup.GetConfigurationBytes();

                        // Apply the appdomain settings to the new appdomain before creating it
                        appDomainInfo.SetConfigurationBytes(currentAppdomainBytes);

                        AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
                        s_resolverLoadedType = loadedType;

                        taskAppDomain = AppDomain.CreateDomain(isOutOfProc ? "taskAppDomain (out-of-proc)" : "taskAppDomain (in-proc)", null, appDomainInfo);

                        if (loadedType.LoadedAssembly != null)
                        {
                            taskAppDomain.Load(loadedType.LoadedAssembly.GetName());
                        }

                        // Hook up last minute dumping of any exceptions
                        taskAppDomain.UnhandledException += new UnhandledExceptionEventHandler(ExceptionHandling.UnhandledExceptionHandler);
                    }
                }
                else
                {
                    // 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 (loadedType.Assembly.AssemblyFile != null)
                {
                    taskInstanceInOtherAppDomain = (ITask)taskAppDomain.CreateInstanceFromAndUnwrap(loadedType.Assembly.AssemblyFile, loadedType.Type.FullName);

                    // this will force evaluation of the task class type and try to load the task assembly
                    Type taskType = taskInstanceInOtherAppDomain.GetType();

                    // If the types don't match, we have a problem. It means that our AppDomain was able to load
                    // a task assembly using Load, and loaded a different one. I don't see any other choice than
                    // to fail here.
                    if (taskType != loadedType.Type)
                    {
                        logError
                        (
                            taskLocation,
                            taskLine,
                            taskColumn,
                            "ConflictingTaskAssembly",
                            loadedType.Assembly.AssemblyFile,
                            loadedType.Type.Assembly.Location
                        );

                        taskInstanceInOtherAppDomain = null;
                    }
                }
                else
                {
                    taskInstanceInOtherAppDomain = (ITask)taskAppDomain.CreateInstanceAndUnwrap(loadedType.Type.Assembly.FullName, loadedType.Type.FullName);
                }

                return(taskInstanceInOtherAppDomain);
            }
            finally
            {
                // Don't leave appdomains open
                if (taskAppDomain != null && taskInstanceInOtherAppDomain == null)
                {
                    AppDomain.Unload(taskAppDomain);
                    RemoveAssemblyResolver();
                }
            }
        }