/// <summary>
        /// This is the main entry point for the GenerateResource task.
        /// </summary>
        /// <returns>true, if task executes successfully</returns>
        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);

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

                        AppDomain appDomain = null;
                        ProcessResourceFiles process = null;

                        try
                        {
                            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
                            {
                                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 (needSeparateAppDomain)
                                {
                                    // Ensure we can unload the other AppDomain, yet still use the
                                    // ITaskItems we got back.  Clone them.
                                    outputResources = CloneValuesInThisAppDomain(outputResources);
                                }

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

                                // 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]);
                                }
                            }

                            process = null;
                        }
                        finally
                        {
                            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;
                            }
                        }
                    }
                }

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

                RemoveUnsuccessfullyCreatedResourcesFromOutputResources();

                RecordFilesWritten();
            }

            return !Log.HasLoggedErrors && outOfProcExecutionSucceeded;
        }
Exemple #2
0
            /// <summary>
            /// Invokes the ToolTask with the given parameters
            /// </summary>
            /// <returns>True if the task succeeded, false otherwise</returns>
            public override bool Execute()
            {
                // If there aren't any input resources, well, we've already succeeded!
                if (ResGen.IsNullOrEmpty(InputFiles))
                {
                    Log.LogMessageFromResources(MessageImportance.Low, "ResGen.NoInputFiles");
                    return(!Log.HasLoggedErrors);
                }

                if (ResGen.IsNullOrEmpty(OutputFiles))
                {
                    GenerateOutputFileNames();
                }

                bool success = false;

                // if command line is too long, fail
                string commandLineCommands = GenerateCommandLineCommands();

                // when comparing command line length, need to add one for leading space added between command arguments and tool name
                if (!string.IsNullOrEmpty(commandLineCommands) && (commandLineCommands.Length + 1) > s_maximumCommandLength)
                {
                    Log.LogErrorWithCodeFromResources("ResGen.CommandTooLong", commandLineCommands.Length);
                    success = false;
                }
                else
                {
                    // Use ToolTaskExtension's Execute()
                    success = base.Execute();
                }

                if (String.IsNullOrEmpty(StronglyTypedLanguage))
                {
                    if (!success)
                    {
                        // One or more of the generated resources was not, in fact generated --
                        // only keep in OutputFiles the ones that actually exist.
                        ITaskItem[]      outputFiles           = this.OutputFiles;
                        List <ITaskItem> successfullyGenerated = new List <ITaskItem>();

                        for (int i = 0; i < outputFiles.Length; i++)
                        {
                            if (File.Exists(outputFiles[i].ItemSpec))
                            {
                                successfullyGenerated.Add(outputFiles[i]);
                            }
                        }

                        this.OutputFiles = successfullyGenerated.ToArray();
                    }
                }
                else
                {
                    ITaskItem outputFile = OutputFiles[0];

                    // if the resource generation was unsuccessful, check to see that the resource file
                    // was in fact generated
                    if (!success)
                    {
                        if (!File.Exists(outputFile.ItemSpec))
                        {
                            this.OutputFiles = new ITaskItem[0];
                        }
                    }

                    // Default the class name if we need to - regardless of whether the STR was successfully generated
                    if (StronglyTypedClassName == null)
                    {
                        StronglyTypedClassName = Path.GetFileNameWithoutExtension(outputFile.ItemSpec);
                    }

                    // Default the filename if we need to - regardless of whether the STR was successfully generated
                    if (StronglyTypedFileName == null)
                    {
                        CodeDomProvider provider = null;
                        try
                        {
                            provider = CodeDomProvider.CreateProvider(StronglyTypedLanguage);
                        }
                        catch (System.Configuration.ConfigurationException)
                        {
                            // If the language can't be found, then ResGen.exe will already have
                            // logged an appropriate error.
                            return(false);
                        }
                        catch (System.Security.SecurityException)
                        {
                            // If the language can't be found, then ResGen.exe will already have
                            // logged an appropriate error.
                            return(false);
                        }

                        StronglyTypedFileName = ProcessResourceFiles.GenerateDefaultStronglyTypedFilename(provider, outputFile.ItemSpec);
                    }
                }

                return(success && !Log.HasLoggedErrors);
            }
 public override bool Execute()
 {
     bool flag = true;
     using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildGenerateResourceBegin, CodeMarkerEvent.perfMSBuildGenerateResourceEnd))
     {
         List<ITaskItem> list;
         List<ITaskItem> list2;
         if ((this.Sources == null) || (this.Sources.Length == 0))
         {
             base.Log.LogMessageFromResources(MessageImportance.Low, "GenerateResource.NoSources", new object[0]);
             this.OutputResources = null;
             return true;
         }
         if (!this.ValidateParameters())
         {
             this.OutputResources = null;
             return false;
         }
         if (!this.CreateOutputResourcesNames())
         {
             this.OutputResources = null;
             return false;
         }
         string rootMarkerResponseFile = null;
         string str2 = null;
         this.trackingInProc = false;
         this.GetResourcesToProcess(out list, out list2);
         if (!base.Log.HasLoggedErrors && (list.Count != 0))
         {
             if (!this.ComputePathToResGen())
             {
                 return false;
             }
             bool flag2 = false;
             try
             {
                 if (this.ExecuteAsTool)
                 {
                     if (this.TrackFileAccess && !FileTracker.ForceOutOfProcTracking(this.resGenType))
                     {
                         try
                         {
                             str2 = FileTracker.EnsureFileTrackerOnPath(this.TrackerFrameworkPath);
                         }
                         catch (Exception exception)
                         {
                             if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception))
                             {
                                 throw;
                             }
                             flag2 = true;
                             base.Log.LogErrorWithCodeFromResources("General.InvalidValue", new object[] { "TrackerFrameworkPath", "GenerateResource" });
                         }
                         if (!flag2)
                         {
                             rootMarkerResponseFile = FileTracker.CreateRootingMarkerResponseFile(this.Sources);
                             FileTracker.StartTrackingContextWithRoot(this.TrackerLogDirectory, generateResourceTlogFilenamePrefix, rootMarkerResponseFile);
                             this.trackingInProc = true;
                         }
                     }
                     if (!flag2)
                     {
                         flag = this.GenerateResourcesUsingResGen(list, list2);
                     }
                 }
                 else
                 {
                     if (this.TrackFileAccess)
                     {
                         try
                         {
                             str2 = FileTracker.EnsureFileTrackerOnPath(this.TrackerFrameworkPath);
                         }
                         catch (Exception exception2)
                         {
                             if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception2))
                             {
                                 throw;
                             }
                             flag2 = true;
                             base.Log.LogErrorWithCodeFromResources("General.InvalidValue", new object[] { "TrackerFrameworkPath", "GenerateResource" });
                         }
                         if (!flag2)
                         {
                             rootMarkerResponseFile = FileTracker.CreateRootingMarkerResponseFile(this.Sources);
                             FileTracker.StartTrackingContextWithRoot(this.TrackerLogDirectory, generateResourceTlogFilenamePrefix, rootMarkerResponseFile);
                             this.trackingInProc = true;
                         }
                     }
                     if (!flag2)
                     {
                         this.LogResgenCommandLine(list, list2);
                         bool flag3 = this.NeedSeparateAppDomain();
                         AppDomain domain = null;
                         ProcessResourceFiles files = null;
                         try
                         {
                             if (flag3)
                             {
                                 this.remotedTaskItems = new List<ITaskItem>();
                                 domain = AppDomain.CreateDomain("generateResourceAppDomain", null, AppDomain.CurrentDomain.SetupInformation);
                                 object obj2 = domain.CreateInstanceFromAndUnwrap(typeof(ProcessResourceFiles).Module.FullyQualifiedName, typeof(ProcessResourceFiles).FullName);
                                 Microsoft.Build.Shared.ErrorUtilities.VerifyThrow(obj2.GetType() == typeof(ProcessResourceFiles), "Somehow got a wrong and possibly incompatible type for ProcessResourceFiles.");
                                 files = (ProcessResourceFiles) obj2;
                                 this.RecordItemsForDisconnectIfNecessary(this.references);
                                 this.RecordItemsForDisconnectIfNecessary(list);
                                 this.RecordItemsForDisconnectIfNecessary(list2);
                             }
                             else
                             {
                                 files = new ProcessResourceFiles();
                             }
                             files.Run(base.Log, this.references, list, list2, this.UseSourcePath, this.StronglyTypedLanguage, this.stronglyTypedNamespace, this.stronglyTypedManifestPrefix, this.StronglyTypedFileName, this.StronglyTypedClassName, this.PublicClass);
                             this.StronglyTypedClassName = files.StronglyTypedClassName;
                             this.StronglyTypedFileName = files.StronglyTypedFilename;
                             this.stronglyTypedResourceSuccessfullyCreated = files.StronglyTypedResourceSuccessfullyCreated;
                             if (files.UnsuccessfullyCreatedOutFiles != null)
                             {
                                 foreach (string str3 in files.UnsuccessfullyCreatedOutFiles)
                                 {
                                     this.unsuccessfullyCreatedOutFiles.Add(str3);
                                 }
                             }
                             files = null;
                         }
                         finally
                         {
                             if (flag3 && (domain != null))
                             {
                                 AppDomain.Unload(domain);
                                 files = null;
                                 domain = null;
                                 if (this.remotedTaskItems != null)
                                 {
                                     foreach (ITaskItem item in this.remotedTaskItems)
                                     {
                                         if (item is MarshalByRefObject)
                                         {
                                             RemotingServices.Disconnect((MarshalByRefObject) item);
                                         }
                                     }
                                 }
                                 this.remotedTaskItems = null;
                             }
                         }
                     }
                 }
             }
             finally
             {
                 if (this.TrackFileAccess)
                 {
                     try
                     {
                         if (this.trackingInProc && !flag2)
                         {
                             FileTracker.WriteContextTLogs(this.TrackerLogDirectory, generateResourceTlogFilenamePrefix);
                             FileTracker.EndTrackingContext();
                         }
                         this.CompactTrackingLogs(!base.Log.HasLoggedErrors && flag);
                     }
                     catch (Exception exception3)
                     {
                         if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception3) && !(exception3 is UnauthorizedAccessException))
                         {
                             throw;
                         }
                         base.Log.LogErrorFromException(exception3);
                     }
                     finally
                     {
                         if (str2 != null)
                         {
                             Environment.SetEnvironmentVariable("PATH", str2);
                         }
                     }
                     if ((rootMarkerResponseFile != null) && File.Exists(rootMarkerResponseFile))
                     {
                         File.Delete(rootMarkerResponseFile);
                     }
                 }
             }
         }
         this.RemoveUnsuccessfullyCreatedResourcesFromOutputResources();
         this.RecordFilesWritten();
     }
     return (!base.Log.HasLoggedErrors && flag);
 }