public override bool Execute()

in src/Tasks/GenerateResource.cs [634:867]


        public override bool Execute()
        {
            bool outOfProcExecutionSucceeded = true;
#if (!STANDALONEBUILD)
            using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildGenerateResourceBegin, CodeMarkerEvent.perfMSBuildGenerateResourceEnd))
#endif
            {
                // If we're extracting ResW files from assemblies (instead of building resources),
                // our Sources can contain PDB's, pictures, and other non-DLL's.  Prune that list.  
                // .NET Framework assemblies are not included.  However, other Microsoft ones
                // such as MSTestFramework may be included (resolved from GetSDKReferenceFiles).
                if (ExtractResWFiles && Sources != null)
                {
                    _satelliteInputs = new List<ITaskItem>();

                    List<ITaskItem> newSources = new List<ITaskItem>();
                    foreach (ITaskItem item in Sources)
                    {
                        if (item.ItemSpec.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
                        {
                            if (item.ItemSpec.EndsWith(".resources.dll", StringComparison.OrdinalIgnoreCase))
                            {
                                _satelliteInputs.Add(item);
                            }
                            else
                            {
                                newSources.Add(item);
                            }
                        }
                    }
                    Sources = newSources.ToArray();
                }


                // If there are no sources to process, just return (with success) and report the condition.
                if ((Sources == null) || (Sources.Length == 0))
                {
                    Log.LogMessageFromResources(MessageImportance.Low, "GenerateResource.NoSources");
                    // Indicate we generated nothing
                    OutputResources = null;
                    return true;
                }

                if (!ValidateParameters())
                {
                    // Indicate we generated nothing
                    OutputResources = null;
                    return false;
                }

                // In the case that OutputResources wasn't set, build up the outputs by transforming the Sources
                // However if we are extracting ResW files, we cannot easily tell which files we'll produce up front,
                // without loading each assembly.
                if (!ExtractResWFiles && !CreateOutputResourcesNames())
                {
                    // Indicate we generated nothing
                    OutputResources = null;
                    return false;
                }

                List<ITaskItem> inputsToProcess;
                List<ITaskItem> outputsToProcess;
                List<ITaskItem> cachedOutputFiles;  // For incremental builds, this is the set of already-existing, up to date files.

                GetResourcesToProcess(out inputsToProcess, out outputsToProcess, out cachedOutputFiles);

                if (inputsToProcess.Count == 0 && !Log.HasLoggedErrors)
                {
                    if (cachedOutputFiles.Count > 0)
                    {
                        OutputResources = cachedOutputFiles.ToArray();
                    }

                    Log.LogMessageFromResources("GenerateResource.NothingOutOfDate");
                }
                else
                {
                    if (!ComputePathToResGen())
                    {
                        // unable to compute the path to resgen.exe and that is necessary to 
                        // continue forward, so return now.
                        return false;
                    }

                    if (ExecuteAsTool)
                    {
                        outOfProcExecutionSucceeded = GenerateResourcesUsingResGen(inputsToProcess, outputsToProcess);
                    }
                    else // Execute in-proc (or in a separate appdomain if necessary)
                    {
                        // Log equivalent command line as this is a convenient way to log all the references, etc
                        // even though we're not actually running resgen.exe
                        LogResgenCommandLine(inputsToProcess, outputsToProcess);

#if FEATURE_APPDOMAIN
                        // Figure out whether a separate AppDomain is required because an assembly would be locked.
                        bool needSeparateAppDomain = NeedSeparateAppDomain();

                        AppDomain appDomain = null;
#endif
                        ProcessResourceFiles process = null;

                        try
                        {
#if FEATURE_APPDOMAIN
                            if (needSeparateAppDomain)
                            {
                                // we're going to be remoting across the appdomain boundary, so
                                // create the list that we'll use to disconnect the taskitems once we're done
                                _remotedTaskItems = new List<ITaskItem>();

                                appDomain = AppDomain.CreateDomain
                                (
                                    "generateResourceAppDomain",
                                    null,
                                    AppDomain.CurrentDomain.SetupInformation
                                );

                                object obj = appDomain.CreateInstanceFromAndUnwrap
                                   (
                                       typeof(ProcessResourceFiles).Module.FullyQualifiedName,
                                       typeof(ProcessResourceFiles).FullName
                                   );

                                Type processType = obj.GetType();
                                ErrorUtilities.VerifyThrow(processType == typeof(ProcessResourceFiles), "Somehow got a wrong and possibly incompatible type for ProcessResourceFiles.");

                                process = (ProcessResourceFiles)obj;

                                RecordItemsForDisconnectIfNecessary(_references);
                                RecordItemsForDisconnectIfNecessary(inputsToProcess);
                                RecordItemsForDisconnectIfNecessary(outputsToProcess);
                            }
                            else
#endif
                            {
                                process = new ProcessResourceFiles();
                            }

                            process.Run(Log, _references, inputsToProcess, _satelliteInputs, outputsToProcess, UseSourcePath,
                                StronglyTypedLanguage, _stronglyTypedNamespace, _stronglyTypedManifestPrefix,
                                StronglyTypedFileName, StronglyTypedClassName, PublicClass,
                                ExtractResWFiles, OutputDirectory);

                            this.StronglyTypedClassName = process.StronglyTypedClassName; // in case a default was chosen
                            this.StronglyTypedFileName = process.StronglyTypedFilename;   // in case a default was chosen
                            _stronglyTypedResourceSuccessfullyCreated = process.StronglyTypedResourceSuccessfullyCreated;
                            if (null != process.UnsuccessfullyCreatedOutFiles)
                            {
                                foreach (string item in process.UnsuccessfullyCreatedOutFiles)
                                {
                                    _unsuccessfullyCreatedOutFiles.Add(item);
                                }
                            }

                            if (ExtractResWFiles)
                            {
                                ITaskItem[] outputResources = process.ExtractedResWFiles.ToArray();
#if FEATURE_APPDOMAIN
                                if (needSeparateAppDomain)
                                {
                                    // Ensure we can unload the other AppDomain, yet still use the
                                    // ITaskItems we got back.  Clone them.
                                    outputResources = CloneValuesInThisAppDomain(outputResources);
                                }
#endif

                                if (cachedOutputFiles.Count > 0)
                                {
                                    OutputResources = new ITaskItem[outputResources.Length + cachedOutputFiles.Count];
                                    outputResources.CopyTo(OutputResources, 0);
                                    cachedOutputFiles.CopyTo(OutputResources, outputResources.Length);
                                }
                                else
                                {
                                    OutputResources = outputResources;
                                }

#if FEATURE_BINARY_SERIALIZATION
                                // Get portable library cache info (and if needed, marshal it to this AD).
                                List<ResGenDependencies.PortableLibraryFile> portableLibraryCacheInfo = process.PortableLibraryCacheInfo;
                                for (int i = 0; i < portableLibraryCacheInfo.Count; i++)
                                {
                                    _cache.UpdatePortableLibrary(portableLibraryCacheInfo[i]);
                                }
#endif
                            }

                            process = null;
                        }
                        finally
                        {
#if FEATURE_APPDOMAIN
                            if (needSeparateAppDomain && appDomain != null)
                            {
                                Log.MarkAsInactive();

                                AppDomain.Unload(appDomain);
                                process = null;
                                appDomain = null;

                                // if we've been asked to remote these items then
                                // we need to disconnect them from .NET Remoting now we're all done with them
                                if (_remotedTaskItems != null)
                                {
                                    foreach (ITaskItem item in _remotedTaskItems)
                                    {
                                        if (item is MarshalByRefObject)
                                        {
                                            // Tell remoting to forget connections to the taskitem
                                            RemotingServices.Disconnect((MarshalByRefObject)item);
                                        }
                                    }
                                }

                                _remotedTaskItems = null;
                            }
#endif
                        }
                    }
                }

#if FEATURE_BINARY_SERIALIZATION
                // And now we serialize the cache to save our resgen linked file resolution for later use.
                WriteStateFile();
#endif

                RemoveUnsuccessfullyCreatedResourcesFromOutputResources();

                RecordFilesWritten();
            }

            return !Log.HasLoggedErrors && outOfProcExecutionSucceeded;
        }