/// <summary> /// Given an MSBuild Target node and associated XmlNamespaceManager, returns a list of VS project parser /// objects, one for each VS project specified in the Target. (There is unlikely to be more than one in any instance.) /// </summary> /// <param name="targetNode">MSBuild Target node</param> /// <param name="xmlnsManager">XML Namespace Manager needed to parse targetNode</param> /// <param name="projRootPath">Path to root FW folder</param> /// <param name="report">Enables error reports to be logged</param> /// <returns>List of VS project parsers if any specified in the target, or else null</returns> public static List <IBuildSystemParser> GetProjectParsers(XmlElement targetNode, XmlNamespaceManager xmlnsManager, string projRootPath, ReportSystem report) { var parsers = new List <IBuildSystemParser>(); var msBuildNodes = targetNode.SelectNodes("msbuild:MSBuild", xmlnsManager); if (msBuildNodes == null) { return(parsers); } foreach (XmlElement msBuildNode in msBuildNodes) { var projectPath = msBuildNode.GetAttribute("Projects").Replace("$(fwrt)", projRootPath); // Was crashing with C:\fwrepo\fw\Lib\src\icu\source\allinone\allinone.sln if (projectPath.EndsWith(".sln")) { continue; } try { parsers.Add(GetProjectParser(projectPath)); } catch (MissingAssemblyInfoException ex) { report.AddSeriousIssue("Error: " + ex.Message); } } return(parsers); }
/// <summary> /// Tests whether the given file's size, date/time, version and MD5 hash are /// consistent with details in the library, so that a patch will succeed. /// For example, if the file's date/time is more recent than that stored in /// the Library, yet the file version has not changed, that is not allowed. /// </summary> /// <param name="file">Element from FileLibrary.xml</param> private void TestLibraryFileDetails(XmlElement file) { var filePath = file.GetAttribute("Path"); var fullFilePath = Path.Combine(_projRootPath, filePath.Replace("\\${config}\\", "\\" + _buildType + "\\")); if (!File.Exists(fullFilePath)) { return; // This should have been dealt with in Patchcorrections.wxs by now. } var libDate = file.GetAttribute("Date"); var libVersion = file.GetAttribute("Version"); //var libSize = file.GetAttribute("Size"); var libMd5 = file.GetAttribute("MD5"); var fileVersionInfo = FileVersionInfo.GetVersionInfo(fullFilePath); var fileVersion = ""; if (fileVersionInfo.FileVersion != null) { fileVersion = fileVersionInfo.FileMajorPart + "." + fileVersionInfo.FileMinorPart + "." + fileVersionInfo.FileBuildPart + "." + fileVersionInfo.FilePrivatePart; } var fi = new FileInfo(fullFilePath); //var realSize = fi.Length; var realDateTime = fi.LastWriteTime.ToString(CultureInfo.InvariantCulture); var realVersion = fileVersion; var realMd5 = CalcFileMd5(fullFilePath); // If the files are not identical, the versions must also be different (if present): if (realMd5 != libMd5 && libVersion != "" && realVersion != "") { if (realVersion == libVersion) { _report.AddSeriousIssue("ERROR #1: File " + filePath + " has been modified since the last release, but its version remains at " + realVersion + ". Patching will fail."); } else { // Although the version may have changed, the installer ignores the last segment (private part) // so we need to warn the user if that is the only part that changed: var realVersionTrunc = fileVersionInfo.FileMajorPart + "." + fileVersionInfo.FileMinorPart + "." + fileVersionInfo.FileBuildPart; var libVersionTrunc = ""; var libVsplit = libVersion.Split('.'); for (int i = 0; i < Math.Min(3, libVsplit.Length); i++) { if (i > 0) { libVersionTrunc += "."; } libVersionTrunc += libVsplit[i]; } if (realVersionTrunc == libVersionTrunc) { _report.AddSeriousIssue("ERROR #8: File " + filePath + " has a version number (" + realVersion + ") that has only changed in the 4th segment since the last release (" + libVersion + "). The 4th version segment is ignored by the installer. Patching will fail."); } } } // The date of the file must not precede that in the library (we will allow up to 24 hours' precedence): var libDateTime = DateTime.Parse(libDate, CultureInfo.InvariantCulture); var fileDateTime = DateTime.Parse(realDateTime, CultureInfo.InvariantCulture); var timeBetweenVersions = fileDateTime.Subtract(libDateTime); if (timeBetweenVersions.TotalHours < -24) { _report.AddSeriousIssue("ERROR #2: File " + filePath + " has a date/time stamp (" + realDateTime + ") that is earlier than a previously released version (" + libDate + "). Patching may fail."); } if (realVersion == "0.0.0.0" && !_versionZeroFiles.Any(path => fullFilePath.ToLowerInvariant().Contains(path.Replace("\\${config}\\", "\\" + _buildType + "\\").ToLowerInvariant()))) { _report.AddSeriousIssue("WARNING #3: File " + filePath + " has a version number of 0.0.0.0. That is very silly, and I don't like it. You'll only regret it later."); } // The version number must not be lower in the latest version than it was in the previous one: if (libVersion.Length > 0 && realVersion.Length == 0) { _report.AddSeriousIssue("ERROR #9: File " + filePath + " had a version of " + libVersion + " in the last release. The version information has since been removed. Patching will fail."); } else { try { if (ParseVersion(realVersion) < ParseVersion(libVersion)) { _report.AddSeriousIssue("ERROR #6: File " + filePath + " had a version of " + libVersion + " in the last release. The version has since been lowered to " + realVersion + ". Patching will fail."); } } catch (Exception e) { _report.AddSeriousIssue("ERROR #7: File " + filePath + " has invalid version number (possibly in FileLibrary.xml): " + e.Message); } } }
/// <summary> /// Given an MSBuild Target node and associated XmlNamespaceManager, returns a list of VS project parser /// objects, one for each VS project specified in the Target. (There is unlikely to be more than one in any instance.) /// </summary> /// <param name="targetNode">MSBuild Target node</param> /// <param name="xmlnsManager">XML Namespace Manager needed to parse targetNode</param> /// <param name="projRootPath">Path to root FW folder</param> /// <param name="report">Enables error reports to be logged</param> /// <returns>List of VS project parsers if any specified in the target, or else null</returns> public static List<IBuildSystemParser> GetProjectParsers(XmlElement targetNode, XmlNamespaceManager xmlnsManager, string projRootPath, ReportSystem report) { var parsers = new List<IBuildSystemParser>(); var msBuildNodes = targetNode.SelectNodes("msbuild:MSBuild", xmlnsManager); if (msBuildNodes == null) return parsers; foreach (XmlElement msBuildNode in msBuildNodes) { var projectPath = msBuildNode.GetAttribute("Projects").Replace("$(fwrt)", projRootPath); // Was crashing with C:\fwrepo\fw\Lib\src\icu\source\allinone\allinone.sln if (projectPath.EndsWith(".sln")) continue; try { parsers.Add(GetProjectParser(projectPath)); } catch (MissingAssemblyInfoException ex) { report.AddSeriousIssue("Error: " + ex.Message); } } return parsers; }