internal static bool GetTableWithEscaping(TaskLoggingHelper log, string parameterName, string syntaxName, string[] propertyNameValueStrings, out Hashtable finalPropertiesTable)
 {
     finalPropertiesTable = null;
     if (propertyNameValueStrings != null)
     {
         finalPropertiesTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
         List<PropertyNameValuePair> list = new List<PropertyNameValuePair>();
         foreach (string str in propertyNameValueStrings)
         {
             int index = str.IndexOf('=');
             if (index != -1)
             {
                 string propertyName = str.Substring(0, index).Trim();
                 string propertyValue = Microsoft.Build.Shared.EscapingUtilities.Escape(str.Substring(index + 1).Trim());
                 if (propertyName.Length == 0)
                 {
                     if (log != null)
                     {
                         log.LogErrorWithCodeFromResources("General.InvalidPropertyError", new object[] { syntaxName, str });
                     }
                     return false;
                 }
                 list.Add(new PropertyNameValuePair(propertyName, propertyValue));
             }
             else if (list.Count > 0)
             {
                 string str4 = Microsoft.Build.Shared.EscapingUtilities.Escape(str.Trim());
                 list[list.Count - 1].Value.Append(';');
                 list[list.Count - 1].Value.Append(str4);
             }
             else
             {
                 if (log != null)
                 {
                     log.LogErrorWithCodeFromResources("General.InvalidPropertyError", new object[] { syntaxName, str });
                 }
                 return false;
             }
         }
         if (log != null)
         {
             log.LogMessageFromText(parameterName, MessageImportance.Low);
         }
         foreach (PropertyNameValuePair pair in list)
         {
             finalPropertiesTable[pair.Name] = pair.Value.ToString();
             if (log != null)
             {
                 log.LogMessageFromText(string.Format(CultureInfo.InvariantCulture, "  {0}={1}", new object[] { pair.Name, pair.Value.ToString() }), MessageImportance.Low);
             }
         }
     }
     return true;
 }
Пример #2
0
        /// <summary>
        /// Reads contents of a key file. Reused from vsdesigner code.
        /// </summary>
        /// <param name="log"></param>
        /// <param name="keyFile"></param>
        /// <param name="keyPair"></param>
        /// <param name="publicKey"></param>
        internal static void ReadKeyFile(TaskLoggingHelper log, string keyFile, out StrongNameKeyPair keyPair, out byte[] publicKey)
        {
            // Initialize parameters
            keyPair = null;
            publicKey = null;

            byte[] keyFileContents;

            try
            {
                // Read the stuff from the file stream
                using (FileStream fs = new FileStream(keyFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    keyFileContents = new byte[(int)fs.Length];
                    fs.Read(keyFileContents, 0, (int)fs.Length);
                }
            }
            catch (ArgumentException e)
            {
                log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", keyFile);
                log.LogErrorFromException(e);
                throw new StrongNameException(e);
            }
            catch (IOException e)
            {
                log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", keyFile);
                log.LogErrorFromException(e);
                throw new StrongNameException(e);
            }
            catch (SecurityException e)
            {
                log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", keyFile);
                log.LogErrorFromException(e);
                throw new StrongNameException(e);
            }

            // Make a new key pair from what we read
            StrongNameKeyPair snp = new StrongNameKeyPair(keyFileContents);

            // If anything fails reading the public key portion of the strong name key pair, then
            // assume that keyFile contained only the public key portion of the public/private pair.
            try
            {
                publicKey = snp.PublicKey;

                // If we didn't throw up to this point then we have a valid public/private key pair,
                // so assign the object just created above to the out parameter.  
                keyPair = snp;
            }
            catch (ArgumentException)
            {
                publicKey = keyFileContents;
            }
        }
 internal static bool GetTable(TaskLoggingHelper log, string parameterName, string[] propertyList, out Hashtable propertiesTable)
 {
     propertiesTable = null;
     if (propertyList != null)
     {
         propertiesTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
         foreach (string str in propertyList)
         {
             string str2 = string.Empty;
             string str3 = string.Empty;
             int index = str.IndexOf('=');
             if (index != -1)
             {
                 str2 = str.Substring(0, index).Trim();
                 str3 = str.Substring(index + 1).Trim();
             }
             if (str2.Length == 0)
             {
                 if (log != null)
                 {
                     log.LogErrorWithCodeFromResources("General.InvalidPropertyError", new object[] { parameterName, str });
                 }
                 return false;
             }
             propertiesTable[str2] = str3;
         }
     }
     return true;
 }
Пример #4
0
        /// <summary>
        /// Returns true if the provided item list contains duplicate items, false otherwise.
        /// </summary>
        /// <param name="itemList"></param>
        /// <param name="disambiguatingMetadataName">Optional name of metadata that may legitimately disambiguate items. May be null.</param>
        /// <param name="parameterName"></param>
        /// <param name="log"></param>
        private static bool ListHasNoDuplicateItems(ITaskItem[] itemList, string parameterName, string disambiguatingMetadataName, TaskLoggingHelper log)
        {
            if (itemList == null || itemList.Length == 0)
            {
                return true;
            }

            Hashtable alreadySeen = new Hashtable(StringComparer.OrdinalIgnoreCase);
            foreach (ITaskItem item in itemList)
            {
                string key;
                string disambiguatingMetadataValue = null;
                if (disambiguatingMetadataName != null)
                {
                    disambiguatingMetadataValue = item.GetMetadata(disambiguatingMetadataName);
                }

                if (disambiguatingMetadataName == null || string.IsNullOrEmpty(disambiguatingMetadataValue))
                {
                    key = item.ItemSpec;
                }
                else
                {
                    key = item.ItemSpec + ":" + disambiguatingMetadataValue;
                }

                if (alreadySeen.ContainsKey(key))
                {
                    if (disambiguatingMetadataName == null || string.IsNullOrEmpty(disambiguatingMetadataValue))
                    {
                        log.LogErrorWithCodeFromResources("General_DuplicateItemsNotSupported", item.ItemSpec, parameterName);
                    }
                    else
                    {
                        log.LogErrorWithCodeFromResources("General_DuplicateItemsNotSupportedWithMetadata", item.ItemSpec, parameterName, disambiguatingMetadataValue, disambiguatingMetadataName);
                    }
                    return false;
                }
                else
                {
                    alreadySeen[key] = string.Empty;
                }
            }

            return true;
        }
 public static bool TryCreateCodeDomProvider(TaskLoggingHelper logger, string stronglyTypedLanguage, out CodeDomProvider provider)
 {
     provider = null;
     try
     {
         provider = CodeDomProvider.CreateProvider(stronglyTypedLanguage);
     }
     catch (ConfigurationException exception)
     {
         logger.LogErrorWithCodeFromResources("GenerateResource.STRCodeDomProviderFailed", new object[] { stronglyTypedLanguage, exception.Message });
         return false;
     }
     catch (SecurityException exception2)
     {
         logger.LogErrorWithCodeFromResources("GenerateResource.STRCodeDomProviderFailed", new object[] { stronglyTypedLanguage, exception2.Message });
         return false;
     }
     return (provider != null);
 }
 internal static void ReadKeyFile(TaskLoggingHelper log, string keyFile, out StrongNameKeyPair keyPair, out byte[] publicKey)
 {
     byte[] buffer;
     keyPair = null;
     publicKey = null;
     try
     {
         using (FileStream stream = new FileStream(keyFile, FileMode.Open, FileAccess.Read, FileShare.Read))
         {
             buffer = new byte[(int) stream.Length];
             stream.Read(buffer, 0, (int) stream.Length);
         }
     }
     catch (ArgumentException exception)
     {
         log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", new object[] { keyFile });
         log.LogErrorFromException(exception);
         throw new StrongNameException(exception);
     }
     catch (IOException exception2)
     {
         log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", new object[] { keyFile });
         log.LogErrorFromException(exception2);
         throw new StrongNameException(exception2);
     }
     catch (SecurityException exception3)
     {
         log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", new object[] { keyFile });
         log.LogErrorFromException(exception3);
         throw new StrongNameException(exception3);
     }
     StrongNameKeyPair pair = new StrongNameKeyPair(buffer);
     try
     {
         publicKey = pair.PublicKey;
         keyPair = pair;
     }
     catch (ArgumentException)
     {
         publicKey = buffer;
     }
 }
 internal static void GetStrongNameKey(TaskLoggingHelper log, string keyFile, string keyContainer, out StrongNameKeyPair keyPair, out byte[] publicKey)
 {
     keyPair = null;
     publicKey = null;
     if ((keyContainer != null) && (keyContainer.Length != 0))
     {
         try
         {
             keyPair = new StrongNameKeyPair(keyContainer);
             publicKey = keyPair.PublicKey;
             return;
         }
         catch (SecurityException exception)
         {
             log.LogErrorWithCodeFromResources("StrongNameUtils.BadKeyContainer", new object[] { keyContainer });
             log.LogErrorFromException(exception);
             throw new StrongNameException(exception);
         }
         catch (ArgumentException exception2)
         {
             log.LogErrorWithCodeFromResources("StrongNameUtils.BadKeyContainer", new object[] { keyContainer });
             log.LogErrorFromException(exception2);
             throw new StrongNameException(exception2);
         }
     }
     if ((keyFile != null) && (keyFile.Length != 0))
     {
         ReadKeyFile(log, keyFile, out keyPair, out publicKey);
     }
 }
 public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> taskParameters, string taskElementContents, IBuildEngine taskFactoryLoggingHost)
 {
     CompilerResults results;
     Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(taskName, "taskName");
     Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(taskParameters, "taskParameters");
     TaskLoggingHelper helper = new TaskLoggingHelper(taskFactoryLoggingHost, taskName) {
         TaskResources = Microsoft.Build.Shared.AssemblyResources.PrimaryResources,
         HelpKeywordPrefix = "MSBuild."
     };
     if (taskElementContents == null)
     {
         helper.LogErrorWithCodeFromResources("Xaml.MissingTaskBody", new object[0]);
         return false;
     }
     this.TaskElementContents = taskElementContents.Trim();
     TaskParser parser = new TaskParser();
     parser.Parse(this.TaskElementContents, taskName);
     this.TaskName = parser.GeneratedTaskName;
     this.TaskNamespace = parser.Namespace;
     CodeCompileUnit compileUnit = new TaskGenerator(parser).GenerateCode();
     Assembly assembly = Assembly.LoadWithPartialName("System");
     Assembly assembly2 = Assembly.LoadWithPartialName("Microsoft.Build.Framework");
     Assembly assembly3 = Assembly.LoadWithPartialName("Microsoft.Build.Utilities.V4.0");
     Assembly assembly4 = Assembly.LoadWithPartialName("Microsoft.Build.Tasks.V4.0");
     CompilerParameters parameters = new CompilerParameters(new string[] { assembly.Location, assembly2.Location, assembly3.Location, assembly4.Location }) {
         GenerateInMemory = true,
         TreatWarningsAsErrors = false
     };
     CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
     bool flag = Environment.GetEnvironmentVariable("MSBUILDWRITEXAMLTASK") == "1";
     if (flag)
     {
         using (StreamWriter writer = new StreamWriter(taskName + "_XamlTask.cs"))
         {
             CodeGeneratorOptions options = new CodeGeneratorOptions {
                 BlankLinesBetweenMembers = true,
                 BracingStyle = "C"
             };
             provider.GenerateCodeFromCompileUnit(compileUnit, writer, options);
         }
         results = provider.CompileAssemblyFromFile(parameters, new string[] { taskName + "_XamlTask.cs" });
     }
     else
     {
         results = provider.CompileAssemblyFromDom(parameters, new CodeCompileUnit[] { compileUnit });
     }
     try
     {
         this.taskAssembly = results.CompiledAssembly;
     }
     catch (FileNotFoundException)
     {
     }
     if (this.taskAssembly == null)
     {
         StringBuilder builder = new StringBuilder();
         builder.AppendLine();
         foreach (CompilerError error in results.Errors)
         {
             if (!error.IsWarning)
             {
                 if (flag)
                 {
                     builder.AppendLine(string.Format(Thread.CurrentThread.CurrentUICulture, "({0},{1}) {2}", new object[] { error.Line, error.Column, error.ErrorText }));
                 }
                 else
                 {
                     builder.AppendLine(error.ErrorText);
                 }
             }
         }
         helper.LogErrorWithCodeFromResources("Xaml.TaskCreationFailed", new object[] { builder.ToString() });
     }
     return !helper.HasLoggedErrors;
 }
 public ITask CreateTask(IBuildEngine loggingHost)
 {
     if (this.compiledAssembly == null)
     {
         return null;
     }
     TaskLoggingHelper helper = new TaskLoggingHelper(loggingHost, this.nameOfTask) {
         TaskResources = Microsoft.Build.Shared.AssemblyResources.PrimaryResources,
         HelpKeywordPrefix = "MSBuild."
     };
     ITask task = Activator.CreateInstance(this.TaskType) as ITask;
     if (task == null)
     {
         helper.LogErrorWithCodeFromResources("CodeTaskFactory.NeedsITaskInterface", new object[] { this.nameOfTask });
     }
     return task;
 }
Пример #10
0
        /// <summary>
        /// MSBuild engine will call this to initialize the factory. This should initialize the factory enough so that the factory can be asked
        ///  whether or not task names can be created by the factory.
        /// </summary>
        public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> taskParameters, string taskElementContents, IBuildEngine taskFactoryLoggingHost)
        {
            ErrorUtilities.VerifyThrowArgumentNull(taskName, "taskName");
            ErrorUtilities.VerifyThrowArgumentNull(taskParameters, "taskParameters");

            TaskLoggingHelper log = new TaskLoggingHelper(taskFactoryLoggingHost, taskName);
            log.TaskResources = AssemblyResources.PrimaryResources;
            log.HelpKeywordPrefix = "MSBuild.";

            if (taskElementContents == null)
            {
                log.LogErrorWithCodeFromResources("Xaml.MissingTaskBody");
                return false;
            }

            TaskElementContents = taskElementContents.Trim();

            // Attempt to load the task
            TaskParser parser = new TaskParser();

            bool parseSuccessful = parser.Parse(TaskElementContents, taskName);

            TaskName = parser.GeneratedTaskName;
            TaskNamespace = parser.Namespace;
            TaskGenerator generator = new TaskGenerator(parser);

            CodeCompileUnit dom = generator.GenerateCode();

            string pathToMSBuildBinaries = ToolLocationHelper.GetPathToBuildTools(ToolLocationHelper.CurrentToolsVersion);

            // create the code generator options    
            // Since we are running msbuild 12.0 these had better load.
            CompilerParameters compilerParameters = new CompilerParameters
                (
                    new string[]
                    {
                        "System.dll",
                        Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Framework.dll"),
                        Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Utilities.Core.dll"),
                        Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Tasks.Core.dll")
                    }

                );

            compilerParameters.GenerateInMemory = true;
            compilerParameters.TreatWarningsAsErrors = false;

            // create the code provider
            CodeDomProvider codegenerator = CodeDomProvider.CreateProvider("cs");
            CompilerResults results;
            bool debugXamlTask = Environment.GetEnvironmentVariable("MSBUILDWRITEXAMLTASK") == "1";
            if (debugXamlTask)
            {
                using (StreamWriter outputWriter = new StreamWriter(taskName + "_XamlTask.cs"))
                {
                    CodeGeneratorOptions options = new CodeGeneratorOptions();
                    options.BlankLinesBetweenMembers = true;
                    options.BracingStyle = "C";

                    codegenerator.GenerateCodeFromCompileUnit(dom, outputWriter, options);
                }

                results = codegenerator.CompileAssemblyFromFile(compilerParameters, taskName + "_XamlTask.cs");
            }
            else
            {
                results = codegenerator.CompileAssemblyFromDom(compilerParameters, new[] { dom });
            }

            try
            {
                _taskAssembly = results.CompiledAssembly;
            }
            catch (FileNotFoundException)
            {
                // This occurs if there is a failure to compile the assembly.  We just pass through because we will take care of the failure below.
            }

            if (_taskAssembly == null)
            {
                StringBuilder errorList = new StringBuilder();
                errorList.AppendLine();
                foreach (CompilerError error in results.Errors)
                {
                    if (error.IsWarning)
                    {
                        continue;
                    }

                    if (debugXamlTask)
                    {
                        errorList.AppendLine(String.Format(Thread.CurrentThread.CurrentUICulture, "({0},{1}) {2}", error.Line, error.Column, error.ErrorText));
                    }
                    else
                    {
                        errorList.AppendLine(error.ErrorText);
                    }
                }

                log.LogErrorWithCodeFromResources("Xaml.TaskCreationFailed", errorList.ToString());
            }

            return !log.HasLoggedErrors;
        }
Пример #11
0
 /// <summary>
 /// Given a key file or container, extract private/public key data. Reused from vsdesigner code.
 /// </summary>
 /// <param name="log"></param>
 /// <param name="keyFile"></param>
 /// <param name="keyContainer"></param>
 /// <param name="keyPair"></param>
 /// <param name="publicKey"></param>
 internal static void GetStrongNameKey(TaskLoggingHelper log, string keyFile, string keyContainer, out StrongNameKeyPair keyPair, out byte[] publicKey)
 {
     // Gets either a strong name key pair from the key file or a key container.
     // If keyFile and keyContainer are both null/zero length then returns null.
     // Initialize parameters
     keyPair = null;
     publicKey = null;
     if (keyContainer != null && keyContainer.Length != 0)
     {
         try
         {
             keyPair = new StrongNameKeyPair(keyContainer);
             publicKey = keyPair.PublicKey;
         }
         catch (SecurityException e)
         {
             log.LogErrorWithCodeFromResources("StrongNameUtils.BadKeyContainer", keyContainer);
             log.LogErrorFromException(e);
             throw new StrongNameException(e);
         }
         catch (ArgumentException e)
         {
             log.LogErrorWithCodeFromResources("StrongNameUtils.BadKeyContainer", keyContainer);
             log.LogErrorFromException(e);
             throw new StrongNameException(e);
         }
     }
     else if (keyFile != null && keyFile.Length != 0)
     {
         ReadKeyFile(log, keyFile, out keyPair, out publicKey);
     }
 }
 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;
 }
Пример #13
0
        /// <summary>
        /// Create an instance of the ITask
        /// </summary>
        public ITask CreateTask(IBuildEngine taskFactoryLoggingHost)
        {
            // The assembly will have been compiled during class factory initialization, create an instance of it
            if (this.compiledAssembly != null)
            {
                // In order to use the resource strings from the tasks assembly we need to register the resources with the task logging helper.
                TaskLoggingHelper log = new TaskLoggingHelper(taskFactoryLoggingHost, nameOfTask);
                log.TaskResources = AssemblyResources.PrimaryResources;
                log.HelpKeywordPrefix = "MSBuild.";

                Type[] exportedTypes = this.compiledAssembly.GetExportedTypes();

                Type fullNameMatch = null;
                Type partialNameMatch = null;

                foreach (Type exportedType in exportedTypes)
                {
                    string exportedTypeName = exportedType.FullName;
                    if (exportedTypeName.Equals(nameOfTask, StringComparison.OrdinalIgnoreCase))
                    {
                        fullNameMatch = exportedType;
                        break;
                    } 
                    else if (partialNameMatch == null && exportedTypeName.EndsWith(nameOfTask, StringComparison.OrdinalIgnoreCase))
                    {
                        partialNameMatch = exportedType;
                    }
                }

                if (fullNameMatch == null && partialNameMatch == null)
                {
                    log.LogErrorWithCodeFromResources("CodeTaskFactory.CouldNotFindTaskInAssembly", nameOfTask);
                    return null;
                }

                this.taskInstance = this.compiledAssembly.CreateInstance(fullNameMatch != null ? fullNameMatch.FullName : partialNameMatch.FullName, true) as ITask;

                if (this.taskInstance == null)
                {
                    log.LogErrorWithCodeFromResources("CodeTaskFactory.NeedsITaskInterface", nameOfTask);
                    return null;
                }

                return this.taskInstance;
            }
            else
            {
                return null;
            }
        }
Пример #14
0
        /// <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;
        }