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