public void TestLogMessageFromResources1() { RunAndCheckTaskLoggingHelper( (tlh) => tlh.LogMessageFromResources("MessageResource1", "foo"), (l) => Assert.IsTrue(l.CheckFullLog("Message from resources with arg 'foo'") == 0, "Message not found") ); }
public static bool FindSandcastleHelpFileBuilder(out ITaskItem toolPath, TaskLoggingHelper log) { bool toolFound = false; toolPath = new TaskItem(); string toolName = "Sandcastle Help File Builder"; string sandcastlePath = PathHelpers.CombinePaths(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "EWSoftware", toolName); if (Directory.Exists(sandcastlePath)) { toolPath.ItemSpec = sandcastlePath; } toolFound = (toolPath.ItemSpec.Length != 0); if (log != null) { if (toolFound) { log.LogMessageFromResources("ToolFound", toolName, toolPath); } else { log.LogMessageFromResources("ToolNotFound", toolName); } } return(toolFound); }
public static bool FindVisualStudio2008(out ITaskItem toolPath, TaskLoggingHelper log) { bool toolFound = false; toolPath = new TaskItem(); string toolName = "Microsoft Visual Studio 2008"; using (Microsoft.Win32.RegistryKey regkey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\9.0")) { if (regkey != null) { toolPath.ItemSpec = (string)regkey.GetValue("toolPath", ""); } } toolFound = (toolPath.ItemSpec.Length != 0); if (log != null) { if (toolFound) { log.LogMessageFromResources("ToolFound", toolName, toolPath); } else { log.LogMessageFromResources("ToolNotFound", toolName); } } return(toolFound); }
public void TestResourceAccess() { MyToolTaskExtension t = new MyToolTaskExtension(); MockEngine engine = new MockEngine(); t.BuildEngine = engine; // No need to actually check the outputted strings. We only care that this doesn't throw, which means that // the resource strings were reachable. // Normal CSC messages first, from private XMakeTasks resources. They should be accessible with t.Log t.Log.LogErrorWithCodeFromResources("Csc.AssemblyAliasContainsIllegalCharacters", "PlanetSide", "Knights of the Old Republic"); t.Log.LogWarningWithCodeFromResources("Csc.InvalidParameter"); t.Log.LogMessageFromResources("Vbc.ParameterHasInvalidValue", "Rome Total War", "Need for Speed Underground"); // Now shared messages. Should be accessible with the private LogShared property PropertyInfo logShared = typeof(ToolTask).GetProperty("LogShared", BindingFlags.Instance | BindingFlags.NonPublic); TaskLoggingHelper log = (TaskLoggingHelper)logShared.GetValue(t, null); log.LogWarningWithCodeFromResources("Shared.FailedCreatingTempFile", "Gothic II"); log.LogMessageFromResources("Shared.CannotConvertStringToBool", "foo"); // Now private Utilities messages. Should be accessible with the private LogPrivate property PropertyInfo logPrivate = typeof(ToolTask).GetProperty("LogPrivate", BindingFlags.Instance | BindingFlags.NonPublic); log = (TaskLoggingHelper)logPrivate.GetValue(t, null); log.LogErrorWithCodeFromResources("ToolTask.CommandTooLong", "Painkiller"); log.LogWarningWithCodeFromResources("ToolTask.CouldNotStartToolExecutable", "Fallout Tactics", "Fallout 2"); log.LogMessageFromResources("ToolsLocationHelper.InvalidRedistFile", "Deus Ex", "Fallout"); }
public static bool FindNUnit(out ITaskItem toolPath, TaskLoggingHelper log) { bool toolFound = false; toolPath = new TaskItem(); string toolName = "NUnit 2.2"; string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), toolName); if (Directory.Exists(path)) { toolPath.ItemSpec = path; } toolFound = (toolPath.ItemSpec.Length != 0); if (log != null) { if (toolFound) { log.LogMessageFromResources("ToolFound", toolName, toolPath); } else { log.LogMessageFromResources("ToolNotFound", toolName); } } return(toolFound); }
/// <summary> /// Reads the specified file from disk into a StateFileBase derived object. /// </summary> /// <param name="stateFile"></param> /// <returns></returns> static internal StateFileBase DeserializeCache(string stateFile, TaskLoggingHelper log, Type requiredReturnType) { StateFileBase retVal = null; // First, we read the cache from disk if one exists, or if one does not exist // then we create one. try { if (!string.IsNullOrEmpty(stateFile) && File.Exists(stateFile)) { using (FileStream s = new FileStream(stateFile, FileMode.Open)) { BinaryFormatter formatter = new BinaryFormatter(); object deserializedObject = formatter.Deserialize(s); retVal = deserializedObject as StateFileBase; // If the deserialized object is null then there would be no cast error but retVal would still be null // only log the message if there would have been a cast error if (retVal == null && deserializedObject != null) { // When upgrading to Visual Studio 2008 and running the build for the first time the resource cache files are replaced which causes a cast error due // to a new version number on the tasks class. "Unable to cast object of type 'Microsoft.Build.Tasks.SystemState' to type 'Microsoft.Build.Tasks.StateFileBase”. // If there is an invalid cast, a message rather than a warning should be emitted. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); } if ((retVal != null) && (!requiredReturnType.IsInstanceOfType(retVal))) { log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); retVal = null; } // If we get back a valid object and internals were changed, things are likely to be null. Check the version before we use it. if (retVal != null && retVal._serializedVersion != CurrentSerializationVersion) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); retVal = null; } } } } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } // The deserialization process seems like it can throw just about // any exception imaginable. Catch them all here. // Not being able to deserialize the cache is not an error, but we let the user know anyway. // Don't want to hold up processing just because we couldn't read the file. log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", stateFile, e.Message); } return(retVal); }
public static bool FindVisualStudioTool(string toolName, out ITaskItem toolPath, TaskLoggingHelper log) { bool toolFound = false; toolPath = new TaskItem(); bool vs2003Found; ITaskItem vs2003toolPath; bool vs2005Found; ITaskItem vs2005toolPath; bool vs2008Found; ITaskItem vs2008toolPath; vs2003Found = FindVisualStudio2003(out vs2003toolPath, log); vs2005Found = FindVisualStudio2005(out vs2005toolPath, log); vs2008Found = FindVisualStudio2008(out vs2008toolPath, log); if (vs2003Found) { if (File.Exists(Path.Combine(vs2003toolPath.ItemSpec, toolName))) { toolPath = vs2003toolPath; } } if (vs2005Found) { if (File.Exists(Path.Combine(vs2005toolPath.ItemSpec, toolName))) { toolPath = vs2005toolPath; } } if (vs2008Found) { if (File.Exists(Path.Combine(vs2008toolPath.ItemSpec, toolName))) { toolPath = vs2008toolPath; } } toolFound = (toolPath.ItemSpec.Length != 0); if (log != null) { if (toolFound) { log.LogMessageFromResources("ToolFound", toolName, toolPath); } else { log.LogMessageFromResources("ToolNotFound", toolName); } } return(toolFound); }
/// <summary> /// Reads the specified file from disk into a StateFileBase derived object. /// </summary> internal static StateFileBase DeserializeCache(string stateFile, TaskLoggingHelper log, Type requiredReturnType) { StateFileBase retVal = null; // First, we read the cache from disk if one exists, or if one does not exist, we create one. try { if (!string.IsNullOrEmpty(stateFile) && FileSystems.Default.FileExists(stateFile)) { using (FileStream s = File.OpenRead(stateFile)) { var translator = BinaryTranslator.GetReadTranslator(s, buffer: null); byte version = 0; translator.Translate(ref version); var constructors = requiredReturnType.GetConstructors(); foreach (var constructor in constructors) { var parameters = constructor.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ITranslator)) { retVal = constructor.Invoke(new object[] { translator }) as StateFileBase; } } // If retVal is still null or the version is wrong, log a message not a warning. This could be a valid cache with the wrong version preventing correct deserialization. // For the latter case, internals may be unexpectedly null. if (retVal == null || version != CurrentSerializationVersion) { // When upgrading to Visual Studio 2008 and running the build for the first time the resource cache files are replaced which causes a cast error due // to a new version number on the tasks class. "Unable to cast object of type 'Microsoft.Build.Tasks.SystemState' to type 'Microsoft.Build.Tasks.StateFileBase". // If there is an invalid cast, a message rather than a warning should be emitted. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); return(null); } else if (!requiredReturnType.IsInstanceOfType(retVal)) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); retVal = null; } } } } catch (Exception e) when(!ExceptionHandling.IsCriticalException(e)) { // The deserialization process seems like it can throw just about // any exception imaginable. Catch them all here. // Not being able to deserialize the cache is not an error, but we let the user know anyway. // Don't want to hold up processing just because we couldn't read the file. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, e.Message); } return(retVal); }
//------------------------------------------------------ // // Internal Helper Methods // //------------------------------------------------------ #region Internal Methods // <summary> // Output the Logo information to the logger for a given task // (Console or registered Loggers). // </summary> internal static void DisplayLogo(TaskLoggingHelper log, string taskName) { string acPath = Assembly.GetExecutingAssembly().Location; FileVersionInfo acFileVersionInfo = FileVersionInfo.GetVersionInfo(acPath); string avalonFileVersion = acFileVersionInfo.FileVersion; log.LogMessage(MessageImportance.Low, Environment.NewLine); log.LogMessageFromResources(MessageImportance.Low, SRID.TaskLogo, taskName, avalonFileVersion); log.LogMessageFromResources(MessageImportance.Low, SRID.TaskRight); log.LogMessage(MessageImportance.Low, Environment.NewLine); }
internal static Dictionary <string, string>?ExtractLookupTable(string stringTable, TaskLoggingHelper?log = null) { if (string.IsNullOrEmpty(stringTable)) { return(null); } Dictionary <string, string> table = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (string s in stringTable.Trim().Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries)) { string[] keyVal = s.Trim().Split(MSBuildConstants.EqualsChar); // Invalid table, don't use it. if (keyVal.Length != 2 || string.IsNullOrEmpty(keyVal[0]) || string.IsNullOrEmpty(keyVal[1])) { log?.LogWarningWithCodeFromResources("GetCompatiblePlatform.InvalidLookupTableFormat", stringTable); return(null); } table[keyVal[0]] = keyVal[1]; } log?.LogMessageFromResources(MessageImportance.Low, "GetCompatiblePlatform.LookupTableParsed", stringTable); return(table); }
internal static StateFileBase DeserializeCache(string stateFile, TaskLoggingHelper log, Type requiredReturnType) { StateFileBase o = null; try { if (((stateFile == null) || (stateFile.Length <= 0)) || !File.Exists(stateFile)) { return(o); } using (FileStream stream = new FileStream(stateFile, FileMode.Open)) { object obj2 = new BinaryFormatter().Deserialize(stream); o = obj2 as StateFileBase; if ((o == null) && (obj2 != null)) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", new object[] { stateFile, log.FormatResourceString("General.IncompatibleStateFileType", new object[0]) }); } if ((o != null) && !requiredReturnType.IsInstanceOfType(o)) { log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", new object[] { stateFile, log.FormatResourceString("General.IncompatibleStateFileType", new object[0]) }); o = null; } } } catch (Exception exception) { log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", new object[] { stateFile, exception.Message }); } return(o); }
bool TryCacheAssemblyIdentityFromPath(string assemblyFile, out string candidateAssemblyLocation) { candidateAssemblyLocation = null; try { Assembly candidateAssembly = Assembly.UnsafeLoadFrom(assemblyFile); if (candidateAssembly != null) { string name = candidateAssembly.FullName; if (name == _msbuildFrameworkName || name == _msbuildUtilitiesName) { // Framework and Utilities are default references but are often // specified in the UsingTask anyway; if so just ignore them. return(false); } candidateAssemblyLocation = candidateAssembly.Location; s_knownReferenceAssemblies[candidateAssembly.FullName] = candidateAssembly; } } catch (BadImageFormatException e) { Debug.Assert(e.Message.Contains("0x80131058"), "Expected Message to contain 0x80131058"); AssemblyName.GetAssemblyName(assemblyFile); candidateAssemblyLocation = assemblyFile; _log.LogMessageFromResources(MessageImportance.Low, "CodeTaskFactory.HaveReflectionOnlyAssembly", assemblyFile); } return(true); }
public static bool FindFxCop(out ITaskItem toolPath, TaskLoggingHelper log) { bool toolFound = false; toolPath = new TaskItem(); string toolName = "Microsoft FxCop"; string fxCop132Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), toolName + " 1.32"); string fxCop135Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), toolName + " 1.35"); string fxCop136Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), toolName + " 1.36"); if (Directory.Exists(fxCop136Path)) { toolPath.ItemSpec = fxCop136Path; } else if (Directory.Exists(fxCop135Path)) { toolPath.ItemSpec = fxCop135Path; } else if (Directory.Exists(fxCop132Path)) { toolPath.ItemSpec = fxCop132Path; } else { toolPath.ItemSpec = String.Empty; } toolFound = (toolPath.ItemSpec.Length != 0); if (log != null) { if (toolFound) { log.LogMessageFromResources("ToolFound", toolName, toolPath); } else { log.LogMessageFromResources("ToolNotFound", toolName); } } return(toolFound); }
/// <summary> /// Read the contents of this object out to the specified file. /// TODO: once all classes derived from StateFileBase adopt the new serialization, we should consider moving this into the base class /// </summary> internal static SystemState DeserializeCacheByTranslator(string stateFile, TaskLoggingHelper log) { // First, we read the cache from disk if one exists, or if one does not exist, we create one. try { if (!string.IsNullOrEmpty(stateFile) && FileSystems.Default.FileExists(stateFile)) { using FileStream s = File.OpenRead(stateFile); var translator = BinaryTranslator.GetReadTranslator(s, buffer: null); // TODO: shared buffering? // verify file signature var contractSignature = translator.Reader.ReadBytes(TranslateContractSignature.Length); var contractVersion = translator.Reader.ReadByte(); if (!contractSignature.SequenceEqual(TranslateContractSignature) || contractVersion != TranslateContractVersion) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); return(null); } SystemState systemState = new SystemState(); systemState.Translate(translator); systemState.isDirty = false; return(systemState); } } catch (Exception e) when(!ExceptionHandling.IsCriticalException(e)) { // The deserialization process seems like it can throw just about // any exception imaginable. Catch them all here. // Not being able to deserialize the cache is not an error, but we let the user know anyway. // Don't want to hold up processing just because we couldn't read the file. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, e.Message); } return(null); }
/// <summary> /// Loads the XSLT to XslCompiledTransform. By default uses Default settings instead of trusted settings. /// </summary> /// <param name="useTrustedSettings">Determines whether or not to use trusted settings.</param> /// <returns>A XslCompiledTransform object.</returns> public XslCompiledTransform LoadXslt(bool useTrustedSettings) { XslCompiledTransform xslct = new XslCompiledTransform(); XsltSettings settings = XsltSettings.Default; switch (_xslMode) { case XslModes.Xslt: xslct.Load(XmlReader.Create(new StringReader(_data)), settings, new XmlUrlResolver()); break; case XslModes.XsltFile: if (useTrustedSettings) { settings = XsltSettings.TrustedXslt; } else { _log.LogMessageFromResources(MessageImportance.Low, "XslTransform.UseTrustedSettings", _data); } xslct.Load(new XPathDocument(XmlReader.Create(_data)), settings, new XmlUrlResolver()); break; #if !MONO case XslModes.XsltCompiledDll: // We accept type in format: assembly_name[;type_name]. type_name may be omitted if assembly has just one type defined string dll = _data; string[] pair = dll.Split(';'); string assemblyPath = pair[0]; string typeName = (pair.Length == 2) ? pair[1] : null; Type t = FindType(assemblyPath, typeName); xslct.Load(t); break; #endif default: ErrorUtilities.ThrowInternalErrorUnreachable(); break; } return(xslct); }
bool TryCacheAssemblyIdentityFromPath(string assemblyFile, out string candidateAssemblyLocation) { candidateAssemblyLocation = null; try { // Framework and Utilities are default references but are often // specified in the UsingTask anyway; if so just ignore them. // // Do this with an explicit upfront check rather than loading the // assembly and then checking its name, because that can cause // the loader to have multiple copies of these assemblies as in // https://github.com/dotnet/msbuild/issues/7108. string name = AssemblyName.GetAssemblyName(assemblyFile).FullName; if (name == _msbuildFrameworkName || name == _msbuildUtilitiesName) { return(false); } Assembly candidateAssembly = Assembly.UnsafeLoadFrom(assemblyFile); if (candidateAssembly != null) { candidateAssemblyLocation = candidateAssembly.Location; s_knownReferenceAssemblies[candidateAssembly.FullName] = candidateAssembly; } } catch (BadImageFormatException e) { Debug.Assert(e.Message.Contains("0x80131058"), "Expected Message to contain 0x80131058"); AssemblyName.GetAssemblyName(assemblyFile); candidateAssemblyLocation = assemblyFile; _log.LogMessageFromResources(MessageImportance.Low, "CodeTaskFactory.HaveReflectionOnlyAssembly", assemblyFile); } return(true); }
/// <summary> /// This method will take a sdkToolsPath and a toolName and return the path to the tool if it is found and exists. /// /// First the method will try and find the tool under the sdkToolsPath taking into account the current processor architecture /// If the tool could not be found the method will try and find the tool under the sdkToolsPath (which should point to the x86 sdk directory). /// /// Finally if the method has not found the tool yet it will fallback and use the toolslocation helper method to try and find the tool. /// </summary> /// <returns>Path including the toolName of the tool if found, null if it is not found</returns> internal static string GeneratePathToTool(FileExists fileExists, string currentArchitecture, string sdkToolsPath, string toolName, TaskLoggingHelper log, bool logErrorsAndWarnings) { // Null until we combine the toolname with the path. string pathToTool = null; if (!String.IsNullOrEmpty(sdkToolsPath)) { string processorSpecificToolDirectory = String.Empty; try { switch (currentArchitecture) { // There may not be an arm directory so we will fall back to the x86 tool location // but if there is then we should try and use it. case ProcessorArchitecture.ARM: processorSpecificToolDirectory = Path.Combine(sdkToolsPath, "arm"); break; case ProcessorArchitecture.AMD64: processorSpecificToolDirectory = Path.Combine(sdkToolsPath, "x64"); break; case ProcessorArchitecture.IA64: processorSpecificToolDirectory = Path.Combine(sdkToolsPath, "ia64"); break; case ProcessorArchitecture.X86: default: processorSpecificToolDirectory = sdkToolsPath; break; } pathToTool = Path.Combine(processorSpecificToolDirectory, toolName); if (!fileExists(pathToTool)) { // Try falling back to the x86 location if (currentArchitecture != ProcessorArchitecture.X86) { pathToTool = Path.Combine(sdkToolsPath, toolName); } } else { return(pathToTool); } } catch (ArgumentException e) { // Catch exceptions from path.combine log.LogErrorWithCodeFromResources("General.SdkToolsPathError", toolName, e.Message); return(null); } if (fileExists(pathToTool)) { return(pathToTool); } else { if (logErrorsAndWarnings) { // Log an error indicating we could not find it in the processor specific architecture or x86 locations. // We could not find the tool at all, lot a error. log.LogWarningWithCodeFromResources("General.PlatformSDKFileNotFoundSdkToolsPath", toolName, processorSpecificToolDirectory, sdkToolsPath); } } } else { if (logErrorsAndWarnings) { log.LogMessageFromResources(MessageImportance.Low, "General.SdkToolsPathNotSpecifiedOrToolDoesNotExist", toolName, sdkToolsPath); } } // Fall back and see if we can find it with the toolsLocation helper methods. This is not optimal because // the location they are looking at is based on when the Microsoft.Build.Utilities.dll was compiled // but it is better than nothing. if (null == pathToTool || !fileExists(pathToTool)) { pathToTool = FindSDKToolUsingToolsLocationHelper(toolName); if (pathToTool == null && logErrorsAndWarnings) { log.LogErrorWithCodeFromResources("General.SdkToolsPathToolDoesNotExist", toolName, sdkToolsPath, ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.VersionLatest, VisualStudioVersion.VersionLatest)); } } return(pathToTool); }
/// <returns>True if the operation was successful</returns> internal static bool ExecuteTargets ( List <ITaskItem> projects, Dictionary <string, string> propertiesTable, string[] undefineProperties, List <string[]> targetLists, bool stopOnFirstFailure, bool rebaseOutputs, IBuildEngine3 buildEngine, TaskLoggingHelper log, List <ITaskItem> targetOutputs, bool unloadProjectsOnCompletion, string toolsVersion ) { bool success = true; // We don't log a message about the project and targets we're going to // build, because it'll all be in the immediately subsequent ProjectStarted event. var projectDirectory = new string[projects.Count]; var projectNames = new string[projects.Count]; var toolsVersions = new string[projects.Count]; var projectProperties = new Dictionary <string, string> [projects.Count]; var undefinePropertiesPerProject = new IList <string> [projects.Count]; for (int i = 0; i < projectNames.Length; i++) { projectNames[i] = null; projectProperties[i] = propertiesTable; if (projects[i] != null) { // Retrieve projectDirectory only the first time. It never changes anyway. string projectPath = FileUtilities.AttemptToShortenPath(projects[i].ItemSpec); projectDirectory[i] = Path.GetDirectoryName(projectPath); projectNames[i] = projects[i].ItemSpec; toolsVersions[i] = toolsVersion; // If the user specified a different set of global properties for this project, then // parse the string containing the properties if (!String.IsNullOrEmpty(projects[i].GetMetadata("Properties"))) { if (!PropertyParser.GetTableWithEscaping (log, ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("General.OverridingProperties", projectNames[i]), "Properties", projects[i].GetMetadata("Properties").Split(MSBuildConstants.SemicolonChar), out Dictionary <string, string> preProjectPropertiesTable) ) { return(false); } projectProperties[i] = preProjectPropertiesTable; } if (undefineProperties != null) { undefinePropertiesPerProject[i] = new List <string>(undefineProperties); } // If the user wanted to undefine specific global properties for this project, parse // that string and remove them now. string projectUndefineProperties = projects[i].GetMetadata("UndefineProperties"); if (!String.IsNullOrEmpty(projectUndefineProperties)) { string[] propertiesToUndefine = projectUndefineProperties.Split(MSBuildConstants.SemicolonChar); if (undefinePropertiesPerProject[i] == null) { undefinePropertiesPerProject[i] = new List <string>(propertiesToUndefine.Length); } if (log != null && propertiesToUndefine.Length > 0) { log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", projectNames[i]); foreach (string property in propertiesToUndefine) { undefinePropertiesPerProject[i].Add(property); log.LogMessageFromText($" {property}", MessageImportance.Low); } } } // If the user specified a different set of global properties for this project, then // parse the string containing the properties if (!String.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties"))) { if (!PropertyParser.GetTableWithEscaping (log, ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("General.AdditionalProperties", projectNames[i]), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(MSBuildConstants.SemicolonChar), out Dictionary <string, string> additionalProjectPropertiesTable) ) { return(false); } var combinedTable = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); // First copy in the properties from the global table that not in the additional properties table if (projectProperties[i] != null) { foreach (KeyValuePair <string, string> entry in projectProperties[i]) { if (!additionalProjectPropertiesTable.ContainsKey(entry.Key)) { combinedTable.Add(entry.Key, entry.Value); } } } // Add all the additional properties foreach (KeyValuePair <string, string> entry in additionalProjectPropertiesTable) { combinedTable.Add(entry.Key, entry.Value); } projectProperties[i] = combinedTable; } // If the user specified a different toolsVersion for this project - then override the setting if (!String.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion"))) { toolsVersions[i] = projects[i].GetMetadata("ToolsVersion"); } } } foreach (string[] targetList in targetLists) { if (stopOnFirstFailure && !success) { // Inform the user that we skipped the remaining targets StopOnFirstFailure=true. log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets"); // We have encountered a failure. Caller has requested that we not // continue with remaining targets. break; } // Send the project off to the build engine. By passing in null to the // first param, we are indicating that the project to build is the same // as the *calling* project file. BuildEngineResult result = buildEngine.BuildProjectFilesInParallel(projectNames, targetList, projectProperties, undefinePropertiesPerProject, toolsVersions, true /* ask that target outputs are returned in the buildengineresult */); bool currentTargetResult = result.Result; IList <IDictionary <string, ITaskItem[]> > targetOutputsPerProject = result.TargetOutputsPerProject; success = success && currentTargetResult; // If the engine was able to satisfy the build request if (currentTargetResult) { for (int i = 0; i < projects.Count; i++) { IEnumerable <string> nonNullTargetList = targetList ?? targetOutputsPerProject[i].Keys; foreach (string targetName in nonNullTargetList) { if (targetOutputsPerProject[i].TryGetValue(targetName, out ITaskItem[] outputItemsFromTarget))
public void TestLogMessageFromResourcesNullMessage() { tlh = new TaskLoggingHelper(task); tlh.LogMessageFromResources(null); }
internal static bool ExecuteTargets(ITaskItem[] projects, Hashtable propertiesTable, string[] undefineProperties, ArrayList targetLists, bool stopOnFirstFailure, bool rebaseOutputs, IBuildEngine3 buildEngine, TaskLoggingHelper log, ArrayList targetOutputs, bool useResultsCache, bool unloadProjectsOnCompletion, string toolsVersion) { bool flag = true; string[] strArray = new string[projects.Length]; string[] projectFileNames = new string[projects.Length]; string[] strArray3 = new string[projects.Length]; IList <IDictionary <string, ITaskItem[]> > targetOutputsPerProject = null; IDictionary[] globalProperties = new IDictionary[projects.Length]; List <string>[] removeGlobalProperties = new List <string> [projects.Length]; for (int i = 0; i < projectFileNames.Length; i++) { projectFileNames[i] = null; globalProperties[i] = propertiesTable; if (projects[i] != null) { string path = Microsoft.Build.Shared.FileUtilities.AttemptToShortenPath(projects[i].ItemSpec); strArray[i] = Path.GetDirectoryName(path); projectFileNames[i] = projects[i].ItemSpec; strArray3[i] = toolsVersion; if (!string.IsNullOrEmpty(projects[i].GetMetadata("Properties"))) { Hashtable hashtable; if (!PropertyParser.GetTableWithEscaping(log, Microsoft.Build.Shared.ResourceUtilities.FormatResourceString("General.OverridingProperties", new object[] { projectFileNames[i] }), "Properties", projects[i].GetMetadata("Properties").Split(new char[] { ';' }), out hashtable)) { return(false); } globalProperties[i] = hashtable; } if (undefineProperties != null) { removeGlobalProperties[i] = new List <string>(undefineProperties); } string metadata = projects[i].GetMetadata("UndefineProperties"); if (!string.IsNullOrEmpty(metadata)) { string[] strArray4 = metadata.Split(new char[] { ';' }); if (removeGlobalProperties[i] == null) { removeGlobalProperties[i] = new List <string>(strArray4.Length); } if ((log != null) && (strArray4.Length > 0)) { log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", new object[] { projectFileNames[i] }); foreach (string str3 in strArray4) { removeGlobalProperties[i].Add(str3); log.LogMessageFromText(string.Format(CultureInfo.InvariantCulture, " {0}", new object[] { str3 }), MessageImportance.Low); } } } if (!string.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties"))) { Hashtable hashtable2; if (!PropertyParser.GetTableWithEscaping(log, Microsoft.Build.Shared.ResourceUtilities.FormatResourceString("General.AdditionalProperties", new object[] { projectFileNames[i] }), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(new char[] { ';' }), out hashtable2)) { return(false); } Hashtable hashtable3 = new Hashtable(StringComparer.OrdinalIgnoreCase); if (globalProperties[i] != null) { foreach (DictionaryEntry entry in globalProperties[i]) { if (!hashtable2.Contains(entry.Key)) { hashtable3.Add(entry.Key, entry.Value); } } } foreach (DictionaryEntry entry2 in hashtable2) { hashtable3.Add(entry2.Key, entry2.Value); } globalProperties[i] = hashtable3; } if (!string.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion"))) { strArray3[i] = projects[i].GetMetadata("ToolsVersion"); } } } foreach (string[] strArray5 in targetLists) { if (stopOnFirstFailure && !flag) { log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets", new object[0]); return(flag); } bool flag2 = true; BuildEngineResult result = buildEngine.BuildProjectFilesInParallel(projectFileNames, strArray5, globalProperties, removeGlobalProperties, strArray3, true); flag2 = result.Result; targetOutputsPerProject = result.TargetOutputsPerProject; flag = flag && flag2; if (flag2) { for (int j = 0; j < projects.Length; j++) { IEnumerable enumerable = (strArray5 != null) ? ((IEnumerable)strArray5) : ((IEnumerable)targetOutputsPerProject[j].Keys); foreach (string str4 in enumerable) { if (targetOutputsPerProject[j].ContainsKey(str4)) { ITaskItem[] c = targetOutputsPerProject[j][str4]; foreach (ITaskItem item in c) { if (projects[j] != null) { if (rebaseOutputs) { try { item.ItemSpec = Path.Combine(strArray[j], item.ItemSpec); } catch (ArgumentException exception) { log.LogWarningWithCodeFromResources(null, projects[j].ItemSpec, 0, 0, 0, 0, "MSBuild.CannotRebaseOutputItemPath", new object[] { item.ItemSpec, exception.Message }); } } projects[j].CopyMetadataTo(item); if (string.IsNullOrEmpty(item.GetMetadata("MSBuildSourceProjectFile"))) { item.SetMetadata("MSBuildSourceProjectFile", projects[j].GetMetadata("FullPath")); } } if (string.IsNullOrEmpty(item.GetMetadata("MSBuildSourceTargetName"))) { item.SetMetadata("MSBuildSourceTargetName", str4); } } targetOutputs.AddRange(c); } } } } } return(flag); }
/// <summary> /// /// </summary> /// <returns>True if the operation was successful</returns> internal static async Task<bool> ExecuteTargets ( ITaskItem[] projects, Hashtable propertiesTable, string[] undefineProperties, ArrayList targetLists, bool stopOnFirstFailure, bool rebaseOutputs, IBuildEngine3 buildEngine, TaskLoggingHelper log, ArrayList targetOutputs, bool useResultsCache, bool unloadProjectsOnCompletion, string toolsVersion ) { bool success = true; // We don't log a message about the project and targets we're going to // build, because it'll all be in the immediately subsequent ProjectStarted event. string[] projectDirectory = new string[projects.Length]; string[] projectNames = new string[projects.Length]; string[] toolsVersions = new string[projects.Length]; IList<IDictionary<string, ITaskItem[]>> targetOutputsPerProject = null; IDictionary[] projectProperties = new IDictionary[projects.Length]; List<string>[] undefinePropertiesPerProject = new List<string>[projects.Length]; for (int i = 0; i < projectNames.Length; i++) { projectNames[i] = null; projectProperties[i] = propertiesTable; if (projects[i] != null) { // Retrieve projectDirectory only the first time. It never changes anyway. string projectPath = FileUtilities.AttemptToShortenPath(projects[i].ItemSpec); projectDirectory[i] = Path.GetDirectoryName(projectPath); projectNames[i] = projects[i].ItemSpec; toolsVersions[i] = toolsVersion; // If the user specified a different set of global properties for this project, then // parse the string containing the properties if (!String.IsNullOrEmpty(projects[i].GetMetadata("Properties"))) { Hashtable preProjectPropertiesTable; if (!PropertyParser.GetTableWithEscaping (log, ResourceUtilities.FormatResourceString("General.OverridingProperties", projectNames[i]), "Properties", projects[i].GetMetadata("Properties").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries), out preProjectPropertiesTable) ) { return false; } projectProperties[i] = preProjectPropertiesTable; } if (undefineProperties != null) { undefinePropertiesPerProject[i] = new List<string>(undefineProperties); } // If the user wanted to undefine specific global properties for this project, parse // that string and remove them now. string projectUndefineProperties = projects[i].GetMetadata("UndefineProperties"); if (!String.IsNullOrEmpty(projectUndefineProperties)) { string[] propertiesToUndefine = projectUndefineProperties.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (undefinePropertiesPerProject[i] == null) { undefinePropertiesPerProject[i] = new List<string>(propertiesToUndefine.Length); } if (log != null && propertiesToUndefine.Length > 0) { log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", projectNames[i]); foreach (string property in propertiesToUndefine) { undefinePropertiesPerProject[i].Add(property); log.LogMessageFromText(String.Format(CultureInfo.InvariantCulture, " {0}", property), MessageImportance.Low); } } } // If the user specified a different set of global properties for this project, then // parse the string containing the properties if (!String.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties"))) { Hashtable additionalProjectPropertiesTable; if (!PropertyParser.GetTableWithEscaping (log, ResourceUtilities.FormatResourceString("General.AdditionalProperties", projectNames[i]), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries), out additionalProjectPropertiesTable) ) { return false; } Hashtable combinedTable = new Hashtable(StringComparer.OrdinalIgnoreCase); // First copy in the properties from the global table that not in the additional properties table if (projectProperties[i] != null) { foreach (DictionaryEntry entry in projectProperties[i]) { if (!additionalProjectPropertiesTable.Contains(entry.Key)) { combinedTable.Add(entry.Key, entry.Value); } } } // Add all the additional properties foreach (DictionaryEntry entry in additionalProjectPropertiesTable) { combinedTable.Add(entry.Key, entry.Value); } projectProperties[i] = combinedTable; } // If the user specified a different toolsVersion for this project - then override the setting if (!String.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion"))) { toolsVersions[i] = projects[i].GetMetadata("ToolsVersion"); } } } foreach (string[] targetList in targetLists) { if (stopOnFirstFailure && !success) { // Inform the user that we skipped the remaining targets StopOnFirstFailure=true. log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets"); // We have encountered a failure. Caller has requested that we not // continue with remaining targets. break; } // Send the project off to the build engine. By passing in null to the // first param, we are indicating that the project to build is the same // as the *calling* project file. bool currentTargetResult = true; TaskHost taskHost = (TaskHost)buildEngine; BuildEngineResult result = await taskHost.InternalBuildProjects(projectNames, targetList, projectProperties, undefinePropertiesPerProject, toolsVersions, true /* ask that target outputs are returned in the buildengineresult */); currentTargetResult = result.Result; targetOutputsPerProject = result.TargetOutputsPerProject; success = success && currentTargetResult; // If the engine was able to satisfy the build request if (currentTargetResult) { for (int i = 0; i < projects.Length; i++) { IEnumerable nonNullTargetList = (targetList != null) ? targetList : targetOutputsPerProject[i].Keys; foreach (string targetName in nonNullTargetList) { if (targetOutputsPerProject[i].ContainsKey(targetName)) { ITaskItem[] outputItemsFromTarget = (ITaskItem[])targetOutputsPerProject[i][targetName]; foreach (ITaskItem outputItemFromTarget in outputItemsFromTarget) { // No need to rebase if the calling project is the same as the callee project // (project == null). Also no point in trying to copy item metadata either, // because no items were passed into the Projects parameter! if (projects[i] != null) { // Rebase the output item paths if necessary. No need to rebase if the calling // project is the same as the callee project (project == null). if (rebaseOutputs) { try { outputItemFromTarget.ItemSpec = Path.Combine(projectDirectory[i], outputItemFromTarget.ItemSpec); } catch (ArgumentException e) { log.LogWarningWithCodeFromResources(null, projects[i].ItemSpec, 0, 0, 0, 0, "MSBuild.CannotRebaseOutputItemPath", outputItemFromTarget.ItemSpec, e.Message); } } // Copy the custom item metadata from the "Projects" items to these // output items. projects[i].CopyMetadataTo(outputItemFromTarget); // Set a metadata on the output items called "MSBuildProjectFile" which tells you which project file produced this item. if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceProjectFile))) { outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceProjectFile, projects[i].GetMetadata(FileUtilities.ItemSpecModifiers.FullPath)); } } // Set a metadata on the output items called "MSBuildTargetName" which tells you which target produced this item. if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceTargetName))) { outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceTargetName, targetName); } } targetOutputs.AddRange(outputItemsFromTarget); } } } } } return success; }
internal static string GetNearestPlatform(string referencedProjectPlatform, string projectReferencePlatformsMetadata, string projectReferenceLookupTableMetadata, string platformLookupTable, string projectPath, string currentProjectPlatform, TaskLoggingHelper?log = null) { Dictionary <string, string>?currentProjectLookupTable = ExtractLookupTable(platformLookupTable, log); if (string.IsNullOrEmpty(projectReferencePlatformsMetadata) && string.IsNullOrEmpty(referencedProjectPlatform)) { log?.LogWarningWithCodeFromResources("GetCompatiblePlatform.NoPlatformsListed", projectPath); return(string.Empty); } // Pull platformLookupTable metadata from the referenced project. This allows custom // mappings on a per-ProjectReference basis. Dictionary <string, string>?projectReferenceLookupTable = ExtractLookupTable(projectReferenceLookupTableMetadata, log); HashSet <string> projectReferencePlatforms = new HashSet <string>(); foreach (string s in projectReferencePlatformsMetadata.Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries)) { projectReferencePlatforms.Add(s); } string buildProjectReferenceAs = string.Empty; // If the referenced project has a defined `Platform` that's compatible, it will build that way by default. // Don't set `buildProjectReferenceAs` and the `_GetProjectReferencePlatformProperties` target will handle the rest. if (!string.IsNullOrEmpty(referencedProjectPlatform) && referencedProjectPlatform.Equals(currentProjectPlatform, StringComparison.OrdinalIgnoreCase)) { log?.LogMessageFromResources(MessageImportance.Low, "GetCompatiblePlatform.ReferencedProjectHasDefinitivePlatform", projectPath, referencedProjectPlatform); } // Prefer matching platforms else if (projectReferencePlatforms.Contains(currentProjectPlatform)) { buildProjectReferenceAs = currentProjectPlatform; log?.LogMessageFromResources(MessageImportance.Low, "GetCompatiblePlatform.SamePlatform"); } // Prioritize platformLookupTable **metadata** attached to the ProjectReference item // before the current project's table. We do this to allow per-ProjectReference fine tuning. else if (projectReferenceLookupTable != null && projectReferenceLookupTable.ContainsKey(currentProjectPlatform) && projectReferencePlatforms.Contains(projectReferenceLookupTable[currentProjectPlatform])) { buildProjectReferenceAs = projectReferenceLookupTable[currentProjectPlatform]; log?.LogMessageFromResources(MessageImportance.Low, "GetCompatiblePlatform.FoundMappingInTable", currentProjectPlatform, buildProjectReferenceAs, projectReferenceLookupTableMetadata); } // Current project's translation table follows else if (currentProjectLookupTable != null && currentProjectLookupTable.ContainsKey(currentProjectPlatform) && projectReferencePlatforms.Contains(currentProjectLookupTable[currentProjectPlatform])) { buildProjectReferenceAs = currentProjectLookupTable[currentProjectPlatform]; log?.LogMessageFromResources(MessageImportance.Low, "GetCompatiblePlatform.FoundMappingInTable", currentProjectPlatform, buildProjectReferenceAs, platformLookupTable); } // AnyCPU if possible else if (projectReferencePlatforms.Contains("AnyCPU")) { buildProjectReferenceAs = "AnyCPU"; log?.LogMessageFromResources(MessageImportance.Low, "GetCompatiblePlatform.AnyCPUDefault"); } else { // Keep NearestPlatform empty, log a warning. Common.CurrentVersion.targets will undefine // Platform/PlatformTarget when this is the case. log?.LogWarningWithCodeFromResources("GetCompatiblePlatform.NoCompatiblePlatformFound", projectPath); } return(buildProjectReferenceAs); }
public void TestLogMessageFromResourcesNullMessage2() { tlh = new TaskLoggingHelper(task); tlh.LogMessageFromResources(MessageImportance.Low, null); }
internal static async Task <bool> ExecuteTargets( ITaskItem[] projects, Dictionary <string, string> propertiesTable, string[] undefineProperties, List <string[]> targetLists, bool stopOnFirstFailure, bool rebaseOutputs, IBuildEngine3 buildEngine, TaskLoggingHelper log, List <ITaskItem> targetOutputs, bool unloadProjectsOnCompletion, string toolsVersion, bool skipNonexistentTargets) { bool success = true; // We don't log a message about the project and targets we're going to // build, because it'll all be in the immediately subsequent ProjectStarted event. var projectDirectory = new string[projects.Length]; var projectNames = new string[projects.Length]; var toolsVersions = new string[projects.Length]; var projectProperties = new Dictionary <string, string> [projects.Length]; var undefinePropertiesPerProject = new List <string> [projects.Length]; for (int i = 0; i < projectNames.Length; i++) { projectNames[i] = null; projectProperties[i] = propertiesTable; if (projects[i] != null) { // Retrieve projectDirectory only the first time. It never changes anyway. string projectPath = FileUtilities.AttemptToShortenPath(projects[i].ItemSpec); projectDirectory[i] = Path.GetDirectoryName(projectPath); projectNames[i] = projects[i].ItemSpec; toolsVersions[i] = toolsVersion; // If the user specified a different set of global properties for this project, then // parse the string containing the properties if (!String.IsNullOrEmpty(projects[i].GetMetadata("Properties"))) { if (!PropertyParser.GetTableWithEscaping (log, ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("General.OverridingProperties", projectNames[i]), "Properties", projects[i].GetMetadata("Properties").Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries), out Dictionary <string, string> preProjectPropertiesTable) ) { return(false); } projectProperties[i] = preProjectPropertiesTable; } if (undefineProperties != null) { undefinePropertiesPerProject[i] = new List <string>(undefineProperties); } // If the user wanted to undefine specific global properties for this project, parse // that string and remove them now. string projectUndefineProperties = projects[i].GetMetadata("UndefineProperties"); if (!String.IsNullOrEmpty(projectUndefineProperties)) { string[] propertiesToUndefine = projectUndefineProperties.Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries); if (undefinePropertiesPerProject[i] == null) { undefinePropertiesPerProject[i] = new List <string>(propertiesToUndefine.Length); } if (log != null && propertiesToUndefine.Length > 0) { log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", projectNames[i]); foreach (string property in propertiesToUndefine) { undefinePropertiesPerProject[i].Add(property); log.LogMessageFromText(String.Format(CultureInfo.InvariantCulture, " {0}", property), MessageImportance.Low); } } } // If the user specified a different set of global properties for this project, then // parse the string containing the properties if (!String.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties"))) { if (!PropertyParser.GetTableWithEscaping (log, ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("General.AdditionalProperties", projectNames[i]), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries), out Dictionary <string, string> additionalProjectPropertiesTable) ) { return(false); } var combinedTable = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); // First copy in the properties from the global table that not in the additional properties table if (projectProperties[i] != null) { foreach (KeyValuePair <string, string> entry in projectProperties[i]) { if (!additionalProjectPropertiesTable.ContainsKey(entry.Key)) { combinedTable.Add(entry.Key, entry.Value); } } } // Add all the additional properties foreach (KeyValuePair <string, string> entry in additionalProjectPropertiesTable) { combinedTable.Add(entry.Key, entry.Value); } projectProperties[i] = combinedTable; } // If the user specified a different toolsVersion for this project - then override the setting if (!String.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion"))) { toolsVersions[i] = projects[i].GetMetadata("ToolsVersion"); } } } foreach (string[] targetList in targetLists) { if (stopOnFirstFailure && !success) { // Inform the user that we skipped the remaining targets StopOnFirstFailure=true. log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets"); // We have encountered a failure. Caller has requested that we not // continue with remaining targets. break; } // Send the project off to the build engine. By passing in null to the // first param, we are indicating that the project to build is the same // as the *calling* project file. var taskHost = (TaskHost)buildEngine; BuildEngineResult result = await taskHost.InternalBuildProjects(projectNames, targetList, projectProperties, undefinePropertiesPerProject, toolsVersions, true /* ask that target outputs are returned in the buildengineresult */, skipNonexistentTargets); bool currentTargetResult = result.Result; IList <IDictionary <string, ITaskItem[]> > targetOutputsPerProject = result.TargetOutputsPerProject; success = success && currentTargetResult; // If the engine was able to satisfy the build request if (currentTargetResult) { for (int i = 0; i < projects.Length; i++) { IEnumerable <string> nonNullTargetList = targetList ?? targetOutputsPerProject[i].Keys; foreach (string targetName in nonNullTargetList) { if (targetOutputsPerProject[i].ContainsKey(targetName)) { ITaskItem[] outputItemsFromTarget = targetOutputsPerProject[i][targetName]; foreach (ITaskItem outputItemFromTarget in outputItemsFromTarget) { // No need to rebase if the calling project is the same as the callee project // (project == null). Also no point in trying to copy item metadata either, // because no items were passed into the Projects parameter! if (projects[i] != null) { // Rebase the output item paths if necessary. No need to rebase if the calling // project is the same as the callee project (project == null). if (rebaseOutputs) { try { outputItemFromTarget.ItemSpec = Path.Combine(projectDirectory[i], outputItemFromTarget.ItemSpec); } catch (ArgumentException e) { log.LogWarningWithCodeFromResources(null, projects[i].ItemSpec, 0, 0, 0, 0, "MSBuild.CannotRebaseOutputItemPath", outputItemFromTarget.ItemSpec, e.Message); } } // Copy the custom item metadata from the "Projects" items to these // output items. projects[i].CopyMetadataTo(outputItemFromTarget); // Set a metadata on the output items called "MSBuildProjectFile" which tells you which project file produced this item. if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceProjectFile))) { outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceProjectFile, projects[i].GetMetadata(FileUtilities.ItemSpecModifiers.FullPath)); } } // Set a metadata on the output items called "MSBuildTargetName" which tells you which target produced this item. if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceTargetName))) { outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceTargetName, targetName); } } targetOutputs.AddRange(outputItemsFromTarget); } } } } } return(success); }
internal static string GeneratePathToTool(Microsoft.Build.Shared.FileExists fileExists, string currentArchitecture, string sdkToolsPath, string toolName, TaskLoggingHelper log, bool logErrorsAndWarnings) { string path = null; if (!string.IsNullOrEmpty(sdkToolsPath)) { string str2 = string.Empty; try { string str4 = currentArchitecture; if (str4 == null) { goto Label_0061; } if (!(str4 == "AMD64")) { if (str4 == "IA64") { goto Label_0053; } if (str4 == "x86") { } goto Label_0061; } str2 = Path.Combine(sdkToolsPath, "x64"); goto Label_0063; Label_0053: str2 = Path.Combine(sdkToolsPath, "ia64"); goto Label_0063; Label_0061: str2 = sdkToolsPath; Label_0063: path = Path.Combine(str2, toolName); if (!fileExists(path)) { if (currentArchitecture != "x86") { path = Path.Combine(sdkToolsPath, toolName); } } else { return(path); } } catch (ArgumentException exception) { log.LogErrorWithCodeFromResources("General.SdkToolsPathError", new object[] { toolName, exception.Message }); return(null); } if (fileExists(path)) { return(path); } if (logErrorsAndWarnings) { log.LogWarningWithCodeFromResources("General.PlatformSDKFileNotFoundSdkToolsPath", new object[] { toolName, str2, sdkToolsPath }); } } else if (logErrorsAndWarnings) { log.LogMessageFromResources(MessageImportance.Low, "General.SdkToolsPathNotSpecifiedOrToolDoesNotExist", new object[] { toolName, sdkToolsPath }); } if ((path == null) || !fileExists(path)) { path = FindSDKToolUsingToolsLocationHelper(toolName); if ((path == null) && logErrorsAndWarnings) { log.LogErrorWithCodeFromResources("General.SdkToolsPathToolDoesNotExist", new object[] { toolName, sdkToolsPath, ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version40) }); } } return(path); }