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; }
/// <summary> /// Writes the contents of this object out to the specified file. /// </summary> /// <param name="stateFile"></param> virtual internal void SerializeCache(string stateFile, TaskLoggingHelper log) { try { if (!string.IsNullOrEmpty(stateFile)) { if (File.Exists(stateFile)) { File.Delete(stateFile); } using (FileStream s = new FileStream(stateFile, FileMode.CreateNew)) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(s, this); } } } catch (Exception e) { // If there was a problem writing the file (like it's read-only or locked on disk, for // example), then eat the exception and log a warning. Otherwise, rethrow. if (ExceptionHandling.NotExpectedSerializationException(e)) throw; // Not being able to serialize 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.CouldNotWriteStateFile", stateFile, e.Message); } }
internal static void LogWarningWithCodeFromResources(TaskLoggingHelper Log, string messageResourceName, params object[] messageArgs) { if (Log != null) { Log.LogWarningWithCodeFromResources(messageResourceName, messageArgs); } }
/// <summary> /// Logs a warning using the specified resource string. /// </summary> /// <param name="messageResourceName">The name of the string resource to load.</param> /// <param name="messageArgs">Optional arguments for formatting the loaded string.</param> /// <exception cref="ArgumentNullException">Thrown when <c>messageResourceName</c> is null.</exception> internal static void LogWarningWithCodeFromResources(TaskLoggingHelper Log, string messageResourceName, params object[] messageArgs) { // Only log when we have been passed a TaskLoggingHelper if (Log != null) { Log.LogWarningWithCodeFromResources(messageResourceName, messageArgs); } }
internal static bool GetPathOfTypeLib(TaskLoggingHelper log, ref System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr, out string typeLibPath) { typeLibPath = ""; try { typeLibPath = Microsoft.Build.Tasks.NativeMethods.QueryPathOfRegTypeLib(ref typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, typeLibAttr.lcid); typeLibPath = Environment.ExpandEnvironmentVariables(typeLibPath); } catch (COMException exception) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotGetPathForTypeLib", new object[] { typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, exception.Message }); return false; } if (((typeLibPath != null) && (typeLibPath.Length > 0)) && (typeLibPath[typeLibPath.Length - 1] == '\0')) { typeLibPath = typeLibPath.Substring(0, typeLibPath.Length - 1); } if ((typeLibPath != null) && (typeLibPath.Length > 0)) { return true; } log.LogWarningWithCodeFromResources("ResolveComReference.CannotGetPathForTypeLib", new object[] { typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, "" }); return false; }
internal static void DeleteFile(string stateFile, TaskLoggingHelper log) { try { if (((stateFile != null) && (stateFile.Length > 0)) && File.Exists(stateFile)) { File.Delete(stateFile); } } catch (Exception exception) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception)) { throw; } log.LogWarningWithCodeFromResources("General.CouldNotDeleteStateFile", new object[] { stateFile, exception.Message }); } }
internal static bool GetTypeLibNameForTypeLibAttrs(TaskLoggingHelper log, System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr, out string typeLibName) { bool flag; typeLibName = ""; ITypeLib typeLib = null; try { try { System.Runtime.InteropServices.ComTypes.TYPELIBATTR typelibattr = typeLibAttr; typeLib = (ITypeLib) Microsoft.Build.Tasks.NativeMethods.LoadRegTypeLib(ref typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum, typelibattr.lcid); } catch (COMException exception) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLib", new object[] { typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, exception.Message }); return false; } string typeLibId = log.FormatResourceString("ResolveComReference.TypeLibAttrId", new object[] { typeLibAttr.guid.ToString(), typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum }); flag = GetTypeLibNameForITypeLib(log, typeLib, typeLibId, out typeLibName); } finally { if (typeLib != null) { Marshal.ReleaseComObject(typeLib); } } return flag; }
/// <summary> /// Old VS projects had some pretty messed-up looking values for the /// "DefineConstants" property. It worked fine in the IDE, because it /// effectively munged up the string so that it ended up being valid for /// the compiler. We do the equivalent munging here now. /// /// Basically, we take the incoming string, and split it on comma/semicolon/space. /// Then we look at the resulting list of strings, and remove any that are /// illegal identifiers, and pass the remaining ones through to the compiler. /// /// Note that CSharp does support assigning a value to the constants ... in /// other words, a constant is either defined or not defined ... it can't have /// an actual value. /// </summary> internal static string GetDefineConstantsSwitch(string originalDefineConstants, TaskLoggingHelper log) { if (originalDefineConstants == null) { return null; } StringBuilder finalDefineConstants = new StringBuilder(); // Split the incoming string on comma/semicolon/space. string[] allIdentifiers = originalDefineConstants.Split(new char[] { ',', ';', ' ' }); // Loop through all the parts, and for the ones that are legal C# identifiers, // add them to the outgoing string. foreach (string singleIdentifier in allIdentifiers) { if (SyntaxFacts.IsValidIdentifier(singleIdentifier)) { // Separate them with a semicolon if there's something already in // the outgoing string. if (finalDefineConstants.Length > 0) { finalDefineConstants.Append(";"); } finalDefineConstants.Append(singleIdentifier); } else if (singleIdentifier.Length > 0) { log.LogWarningWithCodeFromResources("Csc_InvalidParameterWarning", "/define:", singleIdentifier); } } if (finalDefineConstants.Length > 0) { return finalDefineConstants.ToString(); } else { // We wouldn't want to pass in an empty /define: switch on the csc.exe command-line. return null; } }
internal static bool GetTypeLibNameForITypeLib(TaskLoggingHelper log, ITypeLib typeLib, string typeLibId, out string typeLibName) { typeLibName = ""; ITypeLib2 lib = typeLib as ITypeLib2; if (lib == null) { typeLibName = Marshal.GetTypeLibName(typeLib); return true; } try { object pVarVal = null; lib.GetCustData(ref Microsoft.Build.Tasks.NativeMethods.GUID_TYPELIB_NAMESPACE, out pVarVal); if ((pVarVal == null) || (string.Compare(pVarVal.GetType().ToString(), "system.string", StringComparison.OrdinalIgnoreCase) != 0)) { typeLibName = Marshal.GetTypeLibName(typeLib); return true; } typeLibName = (string) pVarVal; if ((typeLibName.Length >= 4) && (string.Compare(typeLibName.Substring(typeLibName.Length - 4), ".dll", StringComparison.OrdinalIgnoreCase) == 0)) { typeLibName = typeLibName.Substring(0, typeLibName.Length - 4); } } catch (COMException exception) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotAccessTypeLibName", new object[] { typeLibId, exception.Message }); typeLibName = Marshal.GetTypeLibName(typeLib); return true; } return true; }
/// <summary> /// Deletes the state file from disk /// </summary> /// <param name="stateFile"></param> /// <param name="log"></param> static internal void DeleteFile(string stateFile, TaskLoggingHelper log) { try { if (stateFile != null && stateFile.Length > 0) { if (File.Exists(stateFile)) { File.Delete(stateFile); } } } catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) { log.LogWarningWithCodeFromResources("General.CouldNotDeleteStateFile", stateFile, e.Message); } }
/// <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; }
/// <summary> /// Utility function for creating a VB-style manifest name from /// a resource name. Note that this function attempts to emulate the /// Everret implementation of this code which can be found by searching for /// ComputeNonWFCResourceName() or ComputeWFCResourceName() in /// \vsproject\langproj\langbldmgrsite.cpp /// </summary> /// <param name="fileName">The file name of the dependent (usually a .resx)</param> /// <param name="linkFileName">The file name of the dependent (usually a .resx)</param> /// <param name="prependCultureAsDirectory">should the culture name be prepended to the manifest name as a path</param> /// <param name="rootNamespace">The root namespace (usually from the project file). May be null</param> /// <param name="dependentUponFileName">The file name of the parent of this dependency (usually a .vb file). May be null</param> /// <param name="culture">The override culture of this resource, if any</param> /// <param name="binaryStream">File contents binary stream, may be null</param> /// <param name="log">Task's TaskLoggingHelper, for logging warnings or errors</param> /// <returns>Returns the manifest name</returns> internal static string CreateManifestNameImpl ( string fileName, string linkFileName, bool prependCultureAsDirectory, // true by default string rootNamespace, // May be null string dependentUponFileName, // May be null string culture, Stream binaryStream, // File contents binary stream, may be null TaskLoggingHelper log ) { // Use the link file name if there is one, otherwise, fall back to file name. string embeddedFileName = linkFileName; if (embeddedFileName == null || embeddedFileName.Length == 0) { embeddedFileName = fileName; } Culture.ItemCultureInfo info = Culture.GetItemCultureInfo(embeddedFileName, dependentUponFileName); // If the item has a culture override, respect that. if (!String.IsNullOrEmpty(culture)) { info.culture = culture; } StringBuilder manifestName = new StringBuilder(); if (binaryStream != null) { // Resource depends on a form. Now, get the form's class name fully // qualified with a namespace. ExtractedClassName result = VisualBasicParserUtilities.GetFirstClassNameFullyQualified(binaryStream); if (result.IsInsideConditionalBlock && log != null) { log.LogWarningWithCodeFromResources("CreateManifestResourceName.DefinitionFoundWithinConditionalDirective", dependentUponFileName, embeddedFileName); } if (result.Name != null && result.Name.Length > 0) { if (rootNamespace != null && rootNamespace.Length > 0) { manifestName.Append(rootNamespace).Append(".").Append(result.Name); } else { manifestName.Append(result.Name); } // Append the culture if there is one. if (info.culture != null && info.culture.Length > 0) { manifestName.Append(".").Append(info.culture); } } } // If there's no manifest name at this point, then fall back to using the // RootNamespace+Base file name if (manifestName.Length == 0) { // If Rootnamespace was null, then it wasn't set from the project resourceFile. // Empty namespaces are allowed. if (rootNamespace != null && rootNamespace.Length > 0) { manifestName.Append(rootNamespace).Append("."); } // only strip extension for .resx and .restext files string sourceExtension = Path.GetExtension(info.cultureNeutralFilename); if ( (0 == String.Compare(sourceExtension, ".resx", StringComparison.OrdinalIgnoreCase)) || (0 == String.Compare(sourceExtension, ".restext", StringComparison.OrdinalIgnoreCase)) || (0 == String.Compare(sourceExtension, ".resources", StringComparison.OrdinalIgnoreCase)) ) { manifestName.Append(Path.GetFileNameWithoutExtension(info.cultureNeutralFilename)); // Append the culture if there is one. if (info.culture != null && info.culture.Length > 0) { manifestName.Append(".").Append(info.culture); } // If the original extension was .resources, add it back if (String.Equals(sourceExtension, ".resources", StringComparison.OrdinalIgnoreCase)) { manifestName.Append(sourceExtension); } } else { manifestName.Append(Path.GetFileName(info.cultureNeutralFilename)); if (prependCultureAsDirectory) { // Prepend the culture as a subdirectory if there is one. if (info.culture != null && info.culture.Length > 0) { manifestName.Insert(0, Path.DirectorySeparatorChar); manifestName.Insert(0, info.culture); } } } } return manifestName.ToString(); }
/* * Method: GetTypeLibNameForTypeLibAttrs * * Gets the name of given type library. */ internal static bool GetTypeLibNameForTypeLibAttrs(TaskLoggingHelper log, bool silent, TYPELIBATTR typeLibAttr, out string typeLibName) { typeLibName = ""; ITypeLib typeLib = null; try { // load our type library try { TYPELIBATTR attr = typeLibAttr; typeLib = (ITypeLib)NativeMethods.LoadRegTypeLib(ref attr.guid, attr.wMajorVerNum, attr.wMinorVerNum, attr.lcid); } catch (COMException ex) { if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, ex.Message); } return false; } string typeLibId = log.FormatResourceString("ResolveComReference.TypeLibAttrId", typeLibAttr.guid.ToString(), typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum); return GetTypeLibNameForITypeLib(log, silent, typeLib, typeLibId, out typeLibName); } finally { if (typeLib != null) Marshal.ReleaseComObject(typeLib); } }
internal static void LogWarningWithCodeFromResources(TaskLoggingHelper Log, string messageResourceName, params object[] messageArgs) { if (Log != null) { Log.LogWarningWithCodeFromResources(messageResourceName, messageArgs); } }
internal static string CreateManifestNameImpl(string fileName, string linkFileName, bool prependCultureAsDirectory, string rootNamespace, string dependentUponFileName, Stream binaryStream, TaskLoggingHelper log) { string str = linkFileName; if ((str == null) || (str.Length == 0)) { str = fileName; } Culture.ItemCultureInfo itemCultureInfo = Culture.GetItemCultureInfo(str, dependentUponFileName); StringBuilder builder = new StringBuilder(); if (binaryStream != null) { ExtractedClassName firstClassNameFullyQualified = VisualBasicParserUtilities.GetFirstClassNameFullyQualified(binaryStream); if (firstClassNameFullyQualified.IsInsideConditionalBlock && (log != null)) { log.LogWarningWithCodeFromResources("CreateManifestResourceName.DefinitionFoundWithinConditionalDirective", new object[] { dependentUponFileName, str }); } if ((firstClassNameFullyQualified.Name != null) && (firstClassNameFullyQualified.Name.Length > 0)) { if ((rootNamespace != null) && (rootNamespace.Length > 0)) { builder.Append(rootNamespace).Append(".").Append(firstClassNameFullyQualified.Name); } else { builder.Append(firstClassNameFullyQualified.Name); } if ((itemCultureInfo.culture != null) && (itemCultureInfo.culture.Length > 0)) { builder.Append(".").Append(itemCultureInfo.culture); } } } if (builder.Length == 0) { if ((rootNamespace != null) && (rootNamespace.Length > 0)) { builder.Append(rootNamespace).Append("."); } string extension = Path.GetExtension(itemCultureInfo.cultureNeutralFilename); if (((string.Compare(extension, ".resx", StringComparison.OrdinalIgnoreCase) == 0) || (string.Compare(extension, ".restext", StringComparison.OrdinalIgnoreCase) == 0)) || (string.Compare(extension, ".resources", StringComparison.OrdinalIgnoreCase) == 0)) { builder.Append(Path.GetFileNameWithoutExtension(itemCultureInfo.cultureNeutralFilename)); if ((itemCultureInfo.culture != null) && (itemCultureInfo.culture.Length > 0)) { builder.Append(".").Append(itemCultureInfo.culture); } if (string.Equals(extension, ".resources", StringComparison.OrdinalIgnoreCase)) { builder.Append(extension); } } else { builder.Append(Path.GetFileName(itemCultureInfo.cultureNeutralFilename)); if ((prependCultureAsDirectory && (itemCultureInfo.culture != null)) && (itemCultureInfo.culture.Length > 0)) { builder.Insert(0, Path.DirectorySeparatorChar); builder.Insert(0, itemCultureInfo.culture); } } } return builder.ToString(); }
/// <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; }
/// <summary> /// Utility function for creating a X#-style manifest name from /// a resource name. Note that this function is inspired by the similar C# function /// </summary> /// <param name="fileName">The file name of the dependent (usually a .resx)</param> /// <param name="linkFileName">The file name of the dependent (usually a .resx)</param> /// <param name="rootNamespace">The root namespace (usually from the project file). May be null</param> /// <param name="prependCultureAsDirectory">should the culture name be prepended to the manifest name as a path</param> /// <param name="dependentUponFileName">The file name of the parent of this dependency (usually a .cs file). May be null</param> /// <param name="culture">The override culture of this resource, if any</param> /// <param name="binaryStream">File contents binary stream, may be null</param> /// <param name="log">Task's TaskLoggingHelper, for logging warnings or errors</param> /// <returns>Returns the manifest name</returns> internal static string CreateManifestNameImpl ( string fileName, string linkFileName, bool prependCultureAsDirectory, string rootNamespace, string dependentUponFileName, string culture, Stream binaryStream, TaskLoggingHelper log ) { string embeddedFileName = linkFileName; // Use the link file name if there is one, otherwise, fall back to file name. if ((embeddedFileName == null) || (embeddedFileName.Length == 0)) { embeddedFileName = fileName; } Culture.ItemCultureInfo info = Culture.GetItemCultureInfo(embeddedFileName, dependentUponFileName); // If the item has a culture override, respect that. if (!string.IsNullOrEmpty(culture)) { info.culture = culture; } StringBuilder manifestName = new StringBuilder(); if (binaryStream != null) { // Resource depends on a form. Now, get the form's class name fully // qualified with a namespace. ExtractedClassName result = CreateXSharpManifestResourceName.GetFirstClassNameFullyQualified(fileName, binaryStream, log); if (result.IsInsideConditionalBlock && log != null) { log.LogWarningWithCodeFromResources("CreateManifestResourceName.DefinitionFoundWithinConditionalDirective", dependentUponFileName, embeddedFileName); } if ((result.Name != null) && (result.Name.Length > 0)) { manifestName.Append(result.Name); if ((info.culture != null) && (info.culture.Length > 0)) { manifestName.Append(".").Append(info.culture); } } } // If there's no manifest name at this point, then fall back to using the // RootNamespace+Filename_with_slashes_converted_to_dots if (manifestName.Length == 0) { // If Rootnamespace was null, then it wasn't set from the project resourceFile. // Empty namespaces are allowed. if ((rootNamespace != null) && (rootNamespace.Length > 0)) { manifestName.Append(rootNamespace).Append("."); } // Replace spaces in the directory name with underscores. Needed for compatibility with Everett. // Note that spaces in the file name itself are preserved. string everettCompatibleDirectoryName = CreateManifestResourceName.MakeValidEverettIdentifier(Path.GetDirectoryName(info.cultureNeutralFilename)); // only strip extension for .resx and .restext files string sourceExtension = Path.GetExtension(info.cultureNeutralFilename); if ( (0 == String.Compare(sourceExtension, ".resx", StringComparison.OrdinalIgnoreCase)) || (0 == String.Compare(sourceExtension, ".restext", StringComparison.OrdinalIgnoreCase)) || (0 == String.Compare(sourceExtension, ".resources", StringComparison.OrdinalIgnoreCase)) ) { manifestName.Append(Path.Combine(everettCompatibleDirectoryName , Path.GetFileNameWithoutExtension(info.cultureNeutralFilename))); // Replace all '\' with '.' manifestName.Replace(Path.DirectorySeparatorChar, '.'); manifestName.Replace(Path.AltDirectorySeparatorChar, '.'); // Append the culture if there is one. if ((info.culture != null) && (info.culture.Length > 0)) { manifestName.Append(".").Append(info.culture); } // If the original extension was .resources, add it back if (string.Equals(sourceExtension, ".resources", StringComparison.OrdinalIgnoreCase)) { manifestName.Append(sourceExtension); } } else { manifestName.Append(Path.Combine(everettCompatibleDirectoryName , Path.GetFileName(info.cultureNeutralFilename))); // Replace all '\' with '.' manifestName.Replace(Path.DirectorySeparatorChar, '.'); manifestName.Replace(Path.AltDirectorySeparatorChar, '.'); // Prepend the culture as a subdirectory if there is one. if (prependCultureAsDirectory) { if (info.culture != null && info.culture.Length > 0) { manifestName.Insert(0, Path.DirectorySeparatorChar); manifestName.Insert(0, info.culture); } } } } return manifestName.ToString(); }
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; }
/* * Method: RemapAdoTypeLib * * Tries to remap an ADO type library to ADO 2.7. If the type library passed in is an older ADO tlb, * then remap it to ADO 2.7 if it's registered on the machine (!). Otherwise don't modify the typelib. * Returns true if the type library passed in was successfully remapped. */ internal static bool RemapAdoTypeLib(TaskLoggingHelper log, bool silent, ref TYPELIBATTR typeLibAttr) { // we only care about ADO 2.0, 2.1, 2.5 or 2.6 here. if (typeLibAttr.wMajorVerNum == 2) { if ((typeLibAttr.wMinorVerNum == 0 && typeLibAttr.guid == s_guidADO20) || (typeLibAttr.wMinorVerNum == 1 && typeLibAttr.guid == s_guidADO21) || (typeLibAttr.wMinorVerNum == 5 && typeLibAttr.guid == s_guidADO25) || (typeLibAttr.wMinorVerNum == 6 && typeLibAttr.guid == s_guidADO26)) { // see if ADO 2.7 is registered. if (!Ado27Installed) { if (!silent) { // it's not registered. Don't change the original typelib then. log.LogWarningWithCodeFromResources("ResolveComReference.FailedToRemapAdoTypeLib", typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, Ado27ErrorMessage); } return false; } typeLibAttr.guid = s_guidADO27; typeLibAttr.wMajorVerNum = 2; typeLibAttr.wMinorVerNum = 7; typeLibAttr.lcid = 0; return true; } } return false; }
/* * Method: GetPathOfTypeLib * * Gets the type lib path for given type lib attributes (reused almost verbatim from vsdesigner utils code) * NOTE: If there's a typelib number at the end of the path, does NOT strip it. */ internal static bool GetPathOfTypeLib(TaskLoggingHelper log, bool silent, ref TYPELIBATTR typeLibAttr, out string typeLibPath) { // Get which file the type library resides in. If the appropriate // file cannot be found then a blank string is returned. typeLibPath = ""; try { // Get the path from the registry // This call has known issues. See http://msdn.microsoft.com/en-us/library/ms221436.aspx for the method and // here for the fix http://support.microsoft.com/kb/982110. Most users from Win7 or Win2008R2 should have already received this post Win7SP1. // In Summary: The issue is about calls to The QueryPathOfRegTypeLib function not returning the correct path for a 32-bit version of a // registered type library in a 64-bit edition of Windows 7 or in Windows Server 2008 R2. It either returns the 64bit path or null. typeLibPath = NativeMethods.QueryPathOfRegTypeLib(ref typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, typeLibAttr.lcid); typeLibPath = Environment.ExpandEnvironmentVariables(typeLibPath); } catch (COMException ex) { if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotGetPathForTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, ex.Message); } return false; } if (typeLibPath != null && typeLibPath.Length > 0) { // We have to check for NULL here because QueryPathOfRegTypeLib() returns // a BSTR with a NULL character appended to it. if (typeLibPath[typeLibPath.Length - 1] == '\0') { typeLibPath = typeLibPath.Substring(0, typeLibPath.Length - 1); } } if (typeLibPath != null && typeLibPath.Length > 0) { return true; } else { if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotGetPathForTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, ""); } return false; } }
internal static bool RemapAdoTypeLib(TaskLoggingHelper log, ref System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr) { if ((typeLibAttr.wMajorVerNum != 2) || ((((typeLibAttr.wMinorVerNum != 0) || (typeLibAttr.guid != guidADO20)) && ((typeLibAttr.wMinorVerNum != 1) || (typeLibAttr.guid != guidADO21))) && (((typeLibAttr.wMinorVerNum != 5) || (typeLibAttr.guid != guidADO25)) && ((typeLibAttr.wMinorVerNum != 6) || !(typeLibAttr.guid == guidADO26))))) { return false; } if (!Ado27Installed) { log.LogWarningWithCodeFromResources("ResolveComReference.FailedToRemapAdoTypeLib", new object[] { typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, Ado27ErrorMessage }); return false; } typeLibAttr.guid = guidADO27; typeLibAttr.wMajorVerNum = 2; typeLibAttr.wMinorVerNum = 7; typeLibAttr.lcid = 0; return true; }
/// <summary> /// Logs a warning using the specified resource string. /// </summary> /// <param name="messageResourceName">The name of the string resource to load.</param> /// <param name="messageArgs">Optional arguments for formatting the loaded string.</param> /// <exception cref="ArgumentNullException">Thrown when <c>messageResourceName</c> is null.</exception> internal static void LogWarningWithCodeFromResources(TaskLoggingHelper Log, string messageResourceName, params object[] messageArgs) { // Only log when we have been passed a TaskLoggingHelper if (Log != null) { Log.LogWarningWithCodeFromResources(messageResourceName, messageArgs); } }
internal virtual void SerializeCache(string stateFile, TaskLoggingHelper log) { try { if ((stateFile != null) && (stateFile.Length > 0)) { if (File.Exists(stateFile)) { File.Delete(stateFile); } using (FileStream stream = new FileStream(stateFile, FileMode.CreateNew)) { new BinaryFormatter().Serialize(stream, this); } } } catch (Exception exception) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception)) { throw; } log.LogWarningWithCodeFromResources("General.CouldNotWriteStateFile", new object[] { stateFile, exception.Message }); } }
/// <summary> /// Deletes the state file from disk /// </summary> /// <param name="stateFile"></param> /// <param name="log"></param> static internal void DeleteFile(string stateFile, TaskLoggingHelper log) { try { if (stateFile != null && stateFile.Length > 0) { if (File.Exists(stateFile)) { File.Delete(stateFile); } } } catch (Exception e) { // If there was a problem deleting the file (like it's read-only or locked on disk, for // example), then eat the exception and log a warning. Otherwise, rethrow. if (ExceptionHandling.NotExpectedException(e)) throw; log.LogWarningWithCodeFromResources("General.CouldNotDeleteStateFile", stateFile, e.Message); } }
/// <summary> /// /// </summary> /// <returns>True if the operation was successful</returns> 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 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(';'), 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[] { ';' }); 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(';'), 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; BuildEngineResult result = buildEngine.BuildProjectFilesInParallel(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; }
/* * Method: GetTypeLibNameForITypeLib * * Gets the name of given type library. */ internal static bool GetTypeLibNameForITypeLib(TaskLoggingHelper log, bool silent, ITypeLib typeLib, string typeLibId, out string typeLibName) { typeLibName = ""; // see if the type library supports ITypeLib2 ITypeLib2 typeLib2 = typeLib as ITypeLib2; if (typeLib2 == null) { // Looks like the type lib doesn't support it. Let's use the Marshal method. typeLibName = Marshal.GetTypeLibName(typeLib); return true; } // Get the custom attribute. If anything fails then just return the // type library name. try { object data = null; typeLib2.GetCustData(ref NativeMethods.GUID_TYPELIB_NAMESPACE, out data); // if returned namespace is null or its type is not System.String, fall back to the default // way of getting the type lib name (just to be safe) if (data == null || string.Compare(data.GetType().ToString(), "system.string", StringComparison.OrdinalIgnoreCase) != 0) { typeLibName = Marshal.GetTypeLibName(typeLib); return true; } // Strip off the DLL extension if it's there typeLibName = (string)data; if (typeLibName.Length >= 4) { if (string.Compare(typeLibName.Substring(typeLibName.Length - 4), ".dll", StringComparison.OrdinalIgnoreCase) == 0) { typeLibName = typeLibName.Substring(0, typeLibName.Length - 4); } } } catch (COMException ex) { // If anything fails log a warning and just return the type library name. if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotAccessTypeLibName", typeLibId, ex.Message); } typeLibName = Marshal.GetTypeLibName(typeLib); return true; } return true; }