private XmlNode GetResourcesNodeForSettings_Helper(CultureInfo culture, CultureInfo altCulture, BuildResults results, ref int codepage, bool fShowWarning) { if (altCulture != null && _cultures.Contains(altCulture.Name.ToLowerInvariant())) { if (fShowWarning && culture != null && results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", culture.Name, altCulture.Name)); codepage = altCulture.TextInfo.ANSICodePage; return (XmlNode)_cultures[altCulture.Name.ToLowerInvariant()]; } return null; }
private bool VerifyHomeSiteInformation(XmlNode packageFileNode, ProductBuilder builder, BuildSettings settings, BuildResults results) { if (settings.ComponentsLocation != ComponentsLocation.HomeSite) { return true; } XmlAttribute homesiteAttribute = packageFileNode.Attributes[HOMESITE_ATTRIBUTE]; if (homesiteAttribute == null && builder.Product.CopyAllPackageFiles != CopyAllFilesType.CopyAllFilesIfNotHomeSite) { if (results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.PackageHomeSiteMissing", builder.Name)); return false; } return true; }
private Package GetPackageForSettings_Helper(CultureInfo culture, CultureInfo altCulture, ProductBuilder builder, BuildResults results, bool fShowWarning) { if (altCulture == null) return null; Package package = builder.Product.Packages.Package(altCulture.Name); if (package != null) { if (fShowWarning && culture != null && results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingProductCulture", culture.Name, builder.Name, altCulture.Name)); return package; } return null; }
private XmlNode GetResourcesNodeForSettings(BuildSettings settings, BuildResults results, ref int codepage) { CultureInfo ci = Util.GetCultureInfoFromString(settings.Culture); CultureInfo fallbackCI = Util.GetCultureInfoFromString(settings.FallbackCulture); XmlNode cultureNode = null; if (ci != null) { // Work through the progression of parent cultures (up until but excluding the invariant culture) -> fallback culture -> parent fallback culture -> default culture -> parent default culture -> any available culture cultureNode = GetResourcesNodeForSettings_Helper(ci, ci, results, ref codepage, false); if (cultureNode != null) return cultureNode; CultureInfo parentCulture = ci.Parent; // Keep going up the chain of parents, stopping at the invariant culture while (parentCulture != null && parentCulture != CultureInfo.InvariantCulture) { cultureNode = GetResourcesNodeForSettings_Helper(ci, parentCulture, results, ref codepage, false); if (cultureNode != null) return cultureNode; parentCulture = parentCulture.Parent; } } if (fallbackCI != null) { cultureNode = GetResourcesNodeForSettings_Helper(ci, fallbackCI, results, ref codepage, true); if (cultureNode != null) return cultureNode; if (!fallbackCI.IsNeutralCulture) { cultureNode = GetResourcesNodeForSettings_Helper(ci, fallbackCI.Parent, results, ref codepage, true); if (cultureNode != null) return cultureNode; } } cultureNode = GetResourcesNodeForSettings_Helper(ci, Util.DefaultCultureInfo, results, ref codepage, true); if (cultureNode != null) return cultureNode; if (!Util.DefaultCultureInfo.IsNeutralCulture) { cultureNode = GetResourcesNodeForSettings_Helper(ci, Util.DefaultCultureInfo.Parent, results, ref codepage, true); if (cultureNode != null) return cultureNode; } IEnumerator keys = _cultures.Keys.GetEnumerator(); keys.MoveNext(); string altCulture = (string)keys.Current; if (ci != null && results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", ci.Name, altCulture)); GetCodePage(altCulture, ref codepage); return (XmlNode)_cultures[altCulture.ToLowerInvariant()]; }
private XmlNode GetResourcesNodeForSettings(BuildSettings settings, BuildResults results, ref int codepage) { CultureInfo cultureInfoFromString = Util.GetCultureInfoFromString(settings.Culture); CultureInfo altCulture = Util.GetCultureInfoFromString(settings.FallbackCulture); XmlNode node = null; if (cultureInfoFromString != null) { node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, cultureInfoFromString, results, ref codepage, false); if (node != null) { return node; } for (CultureInfo info3 = cultureInfoFromString.Parent; (info3 != null) && (info3 != CultureInfo.InvariantCulture); info3 = info3.Parent) { node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, info3, results, ref codepage, false); if (node != null) { return node; } } } if (altCulture != null) { node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, altCulture, results, ref codepage, true); if (node != null) { return node; } if (!altCulture.IsNeutralCulture) { node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, altCulture.Parent, results, ref codepage, true); if (node != null) { return node; } } } node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo, results, ref codepage, true); if (node != null) { return node; } if (!Util.DefaultCultureInfo.IsNeutralCulture) { node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo.Parent, results, ref codepage, true); if (node != null) { return node; } } IEnumerator enumerator = this.cultures.Keys.GetEnumerator(); enumerator.MoveNext(); string current = (string) enumerator.Current; if ((cultureInfoFromString != null) && (results != null)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", new object[] { cultureInfoFromString.Name, current })); } this.GetCodePage(current, ref codepage); return (XmlNode) this.cultures[current.ToLowerInvariant()]; }
private Package GetPackageForSettings(BuildSettings settings, ProductBuilder builder, BuildResults results) { CultureInfo ci = Util.GetCultureInfoFromString(settings.Culture); CultureInfo fallbackCI = Util.GetCultureInfoFromString(settings.FallbackCulture); Package package = null; if (builder.Product.Packages.Count == 0) { if (results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.ProductCultureNotFound", builder.Name)); return null; } if (ci != null) { package = builder.Product.Packages.Package(ci.Name); if (package != null) return package; // Target culture not found? Go through the progression of parent cultures (up until but excluding the invariant culture) -> fallback culture -> parent fallback culture -> default culture -> parent default culture -> any culture available // Note: there is no warning if the parent culture of the requested culture is found CultureInfo parentCulture = ci.Parent; // Keep going up the chain of parents, stopping at the invariant culture while (parentCulture != null && parentCulture != CultureInfo.InvariantCulture) { package = GetPackageForSettings_Helper(ci, parentCulture, builder, results, false); if (package != null) return package; parentCulture = parentCulture.Parent; } } if (fallbackCI != null) { package = GetPackageForSettings_Helper(ci, fallbackCI, builder, results, true); if (package != null) return package; if (!fallbackCI.IsNeutralCulture) { package = GetPackageForSettings_Helper(ci, fallbackCI.Parent, builder, results, true); if (package != null) return package; } } package = GetPackageForSettings_Helper(ci, Util.DefaultCultureInfo, builder, results, true); if (package != null) return package; if (!Util.DefaultCultureInfo.IsNeutralCulture) { package = GetPackageForSettings_Helper(ci, Util.DefaultCultureInfo.Parent, builder, results, true); if (package != null) return package; } if (results != null && ci != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingProductCulture", ci.Name, builder.Name, builder.Product.Packages.Item(0).Culture)); return builder.Product.Packages.Item(0); }
private void ExploreDirectory(string strSubDirectory, XmlElement rootElement) { try { string packagePath = this.PackagePath; string str2 = System.IO.Path.Combine(packagePath, strSubDirectory); string filePath = System.IO.Path.Combine(str2, "product.xml"); string schemaPath = System.IO.Path.Combine(this.SchemaPath, "package.xsd"); ProductValidationResults results = new ProductValidationResults(filePath); XmlDocument document = this.LoadAndValidateXmlDocument(filePath, false, schemaPath, "http://schemas.microsoft.com/developer/2004/01/bootstrapper", results); if (document != null) { bool flag = false; XmlNode node = document.SelectSingleNode("bootstrapper:Product", this.xmlNamespaceManager); if (node != null) { XmlAttribute namedItem = (XmlAttribute) node.Attributes.GetNamedItem("ProductCode"); if (namedItem != null) { XmlNode newChild = rootElement.SelectSingleNode("bootstrapper:Product[@ProductCode='" + namedItem.Value + "']", this.xmlNamespaceManager); if (newChild == null) { newChild = this.CreateProductNode(node); } else { results = (ProductValidationResults) this.validationResults[namedItem]; } XmlNode packageFilesNode = node.SelectSingleNode("bootstrapper:PackageFiles", this.xmlNamespaceManager); XmlNode targetNodes = node.SelectSingleNode("bootstrapper:InstallChecks", this.xmlNamespaceManager); XmlNode node5 = node.SelectSingleNode("bootstrapper:Commands", this.xmlNamespaceManager); if (packageFilesNode != null) { this.UpdatePackageFileNodes(packageFilesNode, System.IO.Path.Combine(packagePath, strSubDirectory), strSubDirectory); this.ReplacePackageFileAttributes(targetNodes, "PackageFile", packageFilesNode, "PackageFile", "OldName", "Name"); this.ReplacePackageFileAttributes(node5, "PackageFile", packageFilesNode, "PackageFile", "OldName", "Name"); this.ReplacePackageFileAttributes(node, "LicenseAgreement", packageFilesNode, "PackageFile", "OldName", "SourcePath"); } foreach (string str5 in Directory.GetDirectories(str2)) { XmlElement baseElement = (XmlElement) this.document.ImportNode(node, true); string path = System.IO.Path.Combine(str5, "package.xml"); string str7 = System.IO.Path.Combine(this.SchemaPath, "package.xsd"); if (File.Exists(path)) { XmlValidationResults results2 = new XmlValidationResults(path); XmlDocument document2 = this.LoadAndValidateXmlDocument(path, false, str7, "http://schemas.microsoft.com/developer/2004/01/bootstrapper", results2); if (document2 != null) { XmlNode node6 = document2.SelectSingleNode("bootstrapper:Package", this.xmlNamespaceManager); if (node6 != null) { XmlElement element2 = (XmlElement) this.document.ImportNode(node6, true); XmlElement targetNode = this.document.CreateElement("Package", "http://schemas.microsoft.com/developer/2004/01/bootstrapper"); XmlNode node7 = element2.SelectSingleNode("bootstrapper:PackageFiles", this.xmlNamespaceManager); targetNodes = element2.SelectSingleNode("bootstrapper:InstallChecks", this.xmlNamespaceManager); node5 = element2.SelectSingleNode("bootstrapper:Commands", this.xmlNamespaceManager); if (node7 != null) { int length = packagePath.Length; if (str5.ToCharArray()[length] == System.IO.Path.DirectorySeparatorChar) { length++; } this.UpdatePackageFileNodes(node7, str5, strSubDirectory); this.ReplacePackageFileAttributes(targetNodes, "PackageFile", node7, "PackageFile", "OldName", "Name"); this.ReplacePackageFileAttributes(node5, "PackageFile", node7, "PackageFile", "OldName", "Name"); this.ReplacePackageFileAttributes(element2, "LicenseAgreement", node7, "PackageFile", "OldName", "SourcePath"); } if (packageFilesNode != null) { this.ReplacePackageFileAttributes(targetNodes, "PackageFile", packageFilesNode, "PackageFile", "OldName", "Name"); this.ReplacePackageFileAttributes(node5, "PackageFile", packageFilesNode, "PackageFile", "OldName", "Name"); this.ReplacePackageFileAttributes(element2, "LicenseAgreement", packageFilesNode, "PackageFile", "OldName", "SourcePath"); } foreach (XmlAttribute attribute2 in element2.Attributes) { targetNode.Attributes.Append((XmlAttribute) targetNode.OwnerDocument.ImportNode(attribute2, false)); } foreach (XmlAttribute attribute3 in baseElement.Attributes) { XmlAttribute attribute = (XmlAttribute) targetNode.OwnerDocument.ImportNode(attribute3, false); this.MergeAttribute(targetNode, attribute); } this.CombineElements(element2, baseElement, "Commands", "PackageFile", targetNode); this.CombineElements(element2, baseElement, "InstallChecks", "Property", targetNode); this.CombineElements(element2, baseElement, "PackageFiles", "Name", targetNode); this.CombineElements(element2, baseElement, "Schedules", "Name", targetNode); this.CombineElements(element2, baseElement, "Strings", "Name", targetNode); this.ReplaceStrings(targetNode); this.CorrectPackageFiles(targetNode); this.AppendNode(baseElement, "RelatedProducts", targetNode); XmlAttribute attribute5 = (XmlAttribute) targetNode.Attributes.GetNamedItem("Culture"); if ((attribute5 != null) && !string.IsNullOrEmpty(attribute5.Value)) { string attributeValue = namedItem.Value + "." + attribute5.Value; this.AddAttribute(targetNode, "PackageCode", attributeValue); if ((results != null) && (results2 != null)) { results.AddPackageResults(attribute5.Value, results2); } newChild.AppendChild(targetNode); flag = true; } } } } } if (flag) { rootElement.AppendChild(newChild); if (!this.validationResults.Contains(namedItem.Value)) { this.validationResults.Add(namedItem.Value, results); } } } } } } catch (XmlException) { } catch (IOException) { } catch (ArgumentException) { } }
public bool UpdateResources(string filename, BuildResults results) { bool returnValue = true; int beginUpdateRetries = 20; // Number of retries const int beginUpdateRetryInterval = 100; // In milliseconds bool endUpdate = false; // Only call EndUpdateResource() if this is true // Directory.GetCurrentDirectory() has previously been set to the project location string filePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename); if (_stringResources.Count == 0 && _fileResources.Count == 0) return true; IntPtr hUpdate = IntPtr.Zero; try { hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false); while (IntPtr.Zero == hUpdate && Marshal.GetHRForLastWin32Error() == ResourceUpdater.ERROR_SHARING_VIOLATION && beginUpdateRetries > 0) // If it equals 0x80070020 (ERROR_SHARING_VIOLATION), sleep & retry { // This warning can be useful for debugging, but shouldn't be displayed to an actual user // results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}, trying again after short sleep", filename, Marshal.GetHRForLastWin32Error()))); hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false); beginUpdateRetries--; Thread.Sleep(beginUpdateRetryInterval); } // If after all that we still failed, throw a build error if (IntPtr.Zero == hUpdate) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return false; } endUpdate = true; if (hUpdate != IntPtr.Zero) { foreach (StringResource resource in _stringResources) { byte[] data = StringToByteArray(resource.Data); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)resource.Type, resource.Name, 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return false; } } if (_fileResources.Count > 0) { int index = 0; byte[] countArray = StringToByteArray(_fileResources.Count.ToString("G", CultureInfo.InvariantCulture)); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, "COUNT", 0, countArray, countArray.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return false; } foreach (FileResource resource in _fileResources) { // Read in the file data int fileLength = 0; byte[] fileContent = null; using (FileStream fs = System.IO.File.OpenRead(resource.Filename)) { fileLength = (int)fs.Length; fileContent = new byte[fileLength]; fs.Read(fileContent, 0, fileLength); } // Update the resources to include this file's data string dataName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", index); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, dataName, 0, fileContent, fileLength)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return false; } // Add this file's key to the resources string keyName = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", index); byte[] data = StringToByteArray(resource.Key); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, keyName, 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return false; } index++; } } } } finally { if (endUpdate && !NativeMethods.EndUpdateResource(hUpdate, false)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); returnValue = false; } } return returnValue; }
private bool AddVerificationInformation(XmlNode packageFileNode, string fileSource, string fileName, ProductBuilder builder, BuildSettings settings, BuildResults results) { XmlAttribute attribute = packageFileNode.Attributes["Hash"]; XmlAttribute attribute2 = packageFileNode.Attributes["PublicKey"]; if (File.Exists(fileSource)) { string publicKeyOfFile = this.GetPublicKeyOfFile(fileSource); if ((attribute == null) && (attribute2 == null)) { if (publicKeyOfFile != null) { this.AddAttribute(packageFileNode, "PublicKey", publicKeyOfFile); } else { this.AddAttribute(packageFileNode, "Hash", this.GetFileHash(fileSource)); } } if (attribute2 != null) { if (publicKeyOfFile != null) { this.ReplaceAttribute(packageFileNode, "PublicKey", publicKeyOfFile); } else { packageFileNode.Attributes.RemoveNamedItem("PublicKey"); if (attribute == null) { this.AddAttribute(packageFileNode, "Hash", this.GetFileHash(fileSource)); } } if (((publicKeyOfFile == null) || !publicKeyOfFile.ToLowerInvariant().Equals(attribute2.Value.ToLowerInvariant())) && (results != null)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", new object[] { "PublicKey", builder.Name, fileSource })); } } if (attribute != null) { string fileHash = this.GetFileHash(fileSource); this.ReplaceAttribute(packageFileNode, "Hash", fileHash); if (!fileHash.ToLowerInvariant().Equals(attribute.Value.ToLowerInvariant()) && (results != null)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", new object[] { "Hash", builder.Name, fileSource })); } } } else if (((settings.ComponentsLocation == ComponentsLocation.HomeSite) && (attribute == null)) && (attribute2 == null)) { if (results != null) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.MissingVerificationInformation", new object[] { fileName, builder.Name })); } return false; } return true; }
public BuildResults Build(BuildSettings settings) { this.results = new BuildResults(); try { if ((settings.ApplicationFile == null) && ((settings.ProductBuilders == null) || (settings.ProductBuilders.Count == 0))) { this.results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.InvalidInput", new object[0])); return this.results; } if (string.IsNullOrEmpty(settings.OutputPath)) { this.results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.NoOutputPath", new object[0])); return this.results; } if (!this.fInitialized) { this.Refresh(); } if (string.IsNullOrEmpty(settings.Culture)) { settings.Culture = this.MapLCIDToCultureName(settings.LCID); } if (string.IsNullOrEmpty(settings.FallbackCulture)) { settings.FallbackCulture = this.MapLCIDToCultureName(settings.FallbackLCID); } this.AddBuiltProducts(settings); ArrayList filesCopied = new ArrayList(); string strOutputExe = System.IO.Path.Combine(settings.OutputPath, "setup.exe"); if (!this.CopySetupToOutputDirectory(settings, strOutputExe)) { return this.results; } ResourceUpdater resourceUpdater = new ResourceUpdater(); if (!this.BuildResources(settings, resourceUpdater)) { return this.results; } this.AddStringResourceForUrl(resourceUpdater, "BASEURL", settings.ApplicationUrl, "ApplicationUrl"); this.AddStringResourceForUrl(resourceUpdater, "COMPONENTSURL", settings.ComponentsUrl, "ComponentsUrl"); this.AddStringResourceForUrl(resourceUpdater, "SUPPORTURL", settings.SupportUrl, "SupportUrl"); if (settings.ComponentsLocation == ComponentsLocation.HomeSite) { resourceUpdater.AddStringResource(40, "HOMESITE", true.ToString()); } XmlElement configElement = this.document.CreateElement("Configuration"); XmlElement newChild = this.CreateApplicationElement(configElement, settings); if (newChild != null) { configElement.AppendChild(newChild); } Hashtable eulas = new Hashtable(); if (!this.BuildPackages(settings, configElement, resourceUpdater, filesCopied, eulas)) { return this.results; } this.DumpXmlToFile(configElement, "bootstrapper.cfg.xml"); string data = this.XmlToConfigurationFile(configElement); resourceUpdater.AddStringResource(0x29, "SETUPCFG", data); this.DumpStringToFile(data, "bootstrapper.cfg", false); foreach (object obj2 in eulas.Values) { string str3; DictionaryEntry entry = (DictionaryEntry) obj2; FileInfo info = new FileInfo(entry.Value.ToString()); using (FileStream stream = info.OpenRead()) { str3 = new StreamReader(stream).ReadToEnd(); } resourceUpdater.AddStringResource(0x2c, entry.Key.ToString(), str3); } resourceUpdater.AddStringResource(0x2c, "COUNT", eulas.Count.ToString(CultureInfo.InvariantCulture)); if (!resourceUpdater.UpdateResources(strOutputExe, this.results)) { return this.results; } this.results.SetKeyFile(strOutputExe); string[] array = new string[filesCopied.Count]; filesCopied.CopyTo(array); this.results.AddComponentFiles(array); this.results.BuildSucceeded(); } catch (Exception exception) { this.results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { exception.Message })); } return this.results; }
private bool VerifyHomeSiteInformation(XmlNode packageFileNode, ProductBuilder builder, BuildSettings settings, BuildResults results) { if (settings.ComponentsLocation != ComponentsLocation.HomeSite) { return true; } if ((packageFileNode.Attributes["HomeSite"] != null) || (builder.Product.CopyAllPackageFiles == CopyAllFilesType.CopyAllFilesIfNotHomeSite)) { return true; } if (results != null) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.PackageHomeSiteMissing", new object[] { builder.Name })); } return false; }
private void OrderProducts(Hashtable availableProducts, Hashtable buildQueue) { bool flag = false; this.loopDependenciesWarnings = new BuildResults(); StringBuilder builder = new StringBuilder(); while (buildQueue.Count > 0) { List<string> list = new List<string>(); foreach (Product product in buildQueue.Values) { if (product.Dependencies.Count == 0) { this.products.Add((Product) availableProducts[product.ProductCode]); this.RemoveDependency(buildQueue, product); list.Add(product.ProductCode); } } foreach (string str in list) { buildQueue.Remove(str); if (flag) { builder.Append(str); builder.Append(", "); } } if ((buildQueue.Count > 0) && (list.Count == 0)) { IDictionaryEnumerator enumerator = buildQueue.GetEnumerator(); enumerator.MoveNext(); ((Product) enumerator.Value).Dependencies.RemoveAll(m => true); flag = true; } if ((builder.Length > 0) && ((buildQueue.Count == 0) || (list.Count == 0))) { builder.Remove(builder.Length - 2, 2); this.loopDependenciesWarnings.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.CircularDependency", new object[] { builder.ToString() })); builder.Remove(0, builder.Length); } } }
private XmlNode GetResourcesNodeForSettings_Helper(CultureInfo culture, CultureInfo altCulture, BuildResults results, ref int codepage, bool fShowWarning) { if ((altCulture == null) || !this.cultures.Contains(altCulture.Name.ToLowerInvariant())) { return null; } if ((fShowWarning && (culture != null)) && (results != null)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", new object[] { culture.Name, altCulture.Name })); } codepage = altCulture.TextInfo.ANSICodePage; return (XmlNode) this.cultures[altCulture.Name.ToLowerInvariant()]; }
private bool AddVerificationInformation(XmlNode packageFileNode, string fileSource, string fileName, ProductBuilder builder, BuildSettings settings, BuildResults results) { XmlAttribute hashAttribute = packageFileNode.Attributes[HASH_ATTRIBUTE]; XmlAttribute publicKeyAttribute = packageFileNode.Attributes[PUBLICKEY_ATTRIBUTE]; if (File.Exists(fileSource)) { string publicKey = GetPublicKeyOfFile(fileSource); if (hashAttribute == null && publicKeyAttribute == null) { // If neither the Hash nor PublicKey attributes were specified in the manifest, add it if (publicKey != null) { AddAttribute(packageFileNode, PUBLICKEY_ATTRIBUTE, publicKey); } else { AddAttribute(packageFileNode, HASH_ATTRIBUTE, GetFileHash(fileSource)); } } if (publicKeyAttribute != null) { // Always use the PublicKey of the file on disk if (publicKey != null) ReplaceAttribute(packageFileNode, PUBLICKEY_ATTRIBUTE, publicKey); else { // File on disk is not signed. Remove the public key info, and make sure the hash is written instead packageFileNode.Attributes.RemoveNamedItem(PUBLICKEY_ATTRIBUTE); if (hashAttribute == null) AddAttribute(packageFileNode, HASH_ATTRIBUTE, GetFileHash(fileSource)); } // If the public key in the file doesn't match the public key on disk, issue a build warning if (publicKey == null || !publicKey.ToLowerInvariant().Equals(publicKeyAttribute.Value.ToLowerInvariant())) { if (results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", PUBLICKEY_ATTRIBUTE, builder.Name, fileSource)); } } if (hashAttribute != null) { string fileHash = GetFileHash(fileSource); // Always use the Hash of the file on disk ReplaceAttribute(packageFileNode, HASH_ATTRIBUTE, fileHash); // If the public key in the file doesn't match the public key on disk, issue a build warning if (!fileHash.ToLowerInvariant().Equals(hashAttribute.Value.ToLowerInvariant())) { if (results != null) results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", "Hash", builder.Name, fileSource)); } } } else if (settings.ComponentsLocation == ComponentsLocation.HomeSite) { if (hashAttribute == null && publicKeyAttribute == null) { if (results != null) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.MissingVerificationInformation", fileName, builder.Name)); } return false; } } return true; }
public bool UpdateResources(string filename, BuildResults results) { bool flag = true; int num = 20; bool flag2 = false; if ((this.stringResources.Count == 0) && (this.fileResources.Count == 0)) { return(true); } IntPtr zero = IntPtr.Zero; try { zero = Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.BeginUpdateResourceW(filename, false); while (((IntPtr.Zero == zero) && (Marshal.GetHRForLastWin32Error() == -2147024864)) && (num > 0)) { zero = Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.BeginUpdateResourceW(filename, false); num--; Thread.Sleep(100); } if (IntPtr.Zero == zero) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } flag2 = true; if (!(zero != IntPtr.Zero)) { return(flag); } foreach (StringResource resource in this.stringResources) { byte[] buffer = this.StringToByteArray(resource.Data); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)resource.Type, resource.Name, 0, buffer, buffer.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } } if (this.fileResources.Count <= 0) { return(flag); } int num2 = 0; byte[] data = this.StringToByteArray(this.fileResources.Count.ToString("G", CultureInfo.InvariantCulture)); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, "COUNT", 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } foreach (FileResource resource2 in this.fileResources) { int count = 0; byte[] buffer3 = null; using (FileStream stream = File.OpenRead(resource2.Filename)) { count = (int)stream.Length; buffer3 = new byte[count]; stream.Read(buffer3, 0, count); } string lpName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", new object[] { num2 }); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, lpName, 0, buffer3, count)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } string str2 = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", new object[] { num2 }); byte[] buffer4 = this.StringToByteArray(resource2.Key); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, str2, 0, buffer4, buffer4.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } num2++; } } finally { if (flag2 && !Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.EndUpdateResource(zero, false)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); flag = false; } } return(flag); }
private void OrderProducts(Hashtable availableProducts, Hashtable buildQueue) { bool loopDetected = false; _loopDependenciesWarnings = new BuildResults(); StringBuilder productsInLoop = new StringBuilder(); while (buildQueue.Count > 0) { List<string> productsToRemove = new List<string>(); foreach (Product p in buildQueue.Values) { if (p.Dependencies.Count == 0) { _products.Add((Product)availableProducts[p.ProductCode]); RemoveDependency(buildQueue, p); productsToRemove.Add(p.ProductCode); } } foreach (string productCode in productsToRemove) { buildQueue.Remove(productCode); if (loopDetected) { productsInLoop.Append(productCode); productsInLoop.Append(", "); } } // If we could not remove any products and there are still products in the queue // there must be a loop in it. We'll break the loop by removing the dependencies // of the first project in the queue; if (buildQueue.Count > 0 && productsToRemove.Count == 0) { IDictionaryEnumerator enumerator = buildQueue.GetEnumerator(); enumerator.MoveNext(); ((Product)enumerator.Value).Dependencies.RemoveAll(m => true); loopDetected = true; } // If we've been in a loop and there are no more products left // or no more products can be installed, we have completely walked that loop // and now is a good time to show the warning message for the loop if (productsInLoop.Length > 0 && (buildQueue.Count == 0 || productsToRemove.Count == 0)) { productsInLoop.Remove(productsInLoop.Length - 2, 2); _loopDependenciesWarnings.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.CircularDependency", productsInLoop.ToString())); productsInLoop.Remove(0, productsInLoop.Length); } } }
/// <summary> /// Generates a bootstrapper based on the specified settings. /// </summary> /// <param name="settings">The properties used to build this bootstrapper.</param> /// <returns>The results of the bootstrapper generation</returns> public BuildResults Build(BuildSettings settings) { _results = new BuildResults(); try { if (settings.ApplicationFile == null && (settings.ProductBuilders == null || settings.ProductBuilders.Count == 0)) { _results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.InvalidInput")); return _results; } if (String.IsNullOrEmpty(settings.OutputPath)) { _results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.NoOutputPath")); return _results; } if (!_fInitialized) Refresh(); if (String.IsNullOrEmpty(settings.Culture)) settings.Culture = MapLCIDToCultureName(settings.LCID); if (String.IsNullOrEmpty(settings.FallbackCulture)) settings.FallbackCulture = MapLCIDToCultureName(settings.FallbackLCID); if (String.IsNullOrEmpty(settings.Culture) || settings.Culture == "*") { settings.Culture = settings.FallbackCulture; } AddBuiltProducts(settings); ArrayList componentFilesCopied = new ArrayList(); // Copy setup.bin to the output directory string strOutputExe = System.IO.Path.Combine(settings.OutputPath, SETUP_EXE); if (!CopySetupToOutputDirectory(settings, strOutputExe)) { // Appropriate messages should have been stuffed into the results already return _results; } ResourceUpdater resourceUpdater = new ResourceUpdater(); // Build up the String table for setup.exe if (!BuildResources(settings, resourceUpdater)) { // Appropriate messages should have been stuffed into the results already return _results; } AddStringResourceForUrl(resourceUpdater, "BASEURL", settings.ApplicationUrl, "ApplicationUrl"); AddStringResourceForUrl(resourceUpdater, "COMPONENTSURL", settings.ComponentsUrl, "ComponentsUrl"); AddStringResourceForUrl(resourceUpdater, "SUPPORTURL", settings.SupportUrl, "SupportUrl"); if (settings.ComponentsLocation == ComponentsLocation.HomeSite) { resourceUpdater.AddStringResource(40, "HOMESITE", true.ToString()); } XmlElement configElement = _document.CreateElement("Configuration"); XmlElement applicationElement = CreateApplicationElement(configElement, settings); if (applicationElement != null) { configElement.AppendChild(applicationElement); } // Key: File hash, Value: A DictionaryEntry whose Key is "EULAx" and value is a // fully qualified path to a eula. It can be any eula that matches the hash. Hashtable eulas = new Hashtable(); // Copy package files, add each Package config info to the config file if (!BuildPackages(settings, configElement, resourceUpdater, componentFilesCopied, eulas)) return _results; // Transform the configuration xml into something the bootstrapper will understand DumpXmlToFile(configElement, "bootstrapper.cfg.xml"); string config = XmlToConfigurationFile(configElement); resourceUpdater.AddStringResource(41, "SETUPCFG", config); DumpStringToFile(config, "bootstrapper.cfg", false); // Put eulas in the resource stream foreach (object obj in eulas.Values) { DictionaryEntry de = (DictionaryEntry)obj; string data; FileInfo fi = new System.IO.FileInfo(de.Value.ToString()); using (FileStream fs = fi.OpenRead()) { data = new StreamReader(fs).ReadToEnd(); } resourceUpdater.AddStringResource(44, de.Key.ToString(), data); } resourceUpdater.AddStringResource(44, "COUNT", eulas.Count.ToString(CultureInfo.InvariantCulture)); if (!resourceUpdater.UpdateResources(strOutputExe, _results)) { return _results; } _results.SetKeyFile(strOutputExe); string[] componentFiles = new string[componentFilesCopied.Count]; componentFilesCopied.CopyTo(componentFiles); _results.AddComponentFiles(componentFiles); _results.BuildSucceeded(); } catch (Exception ex) { _results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", ex.Message)); } return _results; }
public bool UpdateResources(string filename, BuildResults results) { bool returnValue = true; int beginUpdateRetries = 20; // Number of retries const int beginUpdateRetryInterval = 100; // In milliseconds bool endUpdate = false; // Only call EndUpdateResource() if this is true // Directory.GetCurrentDirectory() has previously been set to the project location string filePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename); if (_stringResources.Count == 0 && _fileResources.Count == 0) { return(true); } IntPtr hUpdate = IntPtr.Zero; try { hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false); while (IntPtr.Zero == hUpdate && Marshal.GetHRForLastWin32Error() == ResourceUpdater.ERROR_SHARING_VIOLATION && beginUpdateRetries > 0) // If it equals 0x80070020 (ERROR_SHARING_VIOLATION), sleep & retry { // This warning can be useful for debugging, but shouldn't be displayed to an actual user // results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}, trying again after short sleep", filename, Marshal.GetHRForLastWin32Error()))); hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false); beginUpdateRetries--; Thread.Sleep(beginUpdateRetryInterval); } // If after all that we still failed, throw a build error if (IntPtr.Zero == hUpdate) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } endUpdate = true; if (hUpdate != IntPtr.Zero) { foreach (StringResource resource in _stringResources) { byte[] data = StringToByteArray(resource.Data); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)resource.Type, resource.Name, 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } } if (_fileResources.Count > 0) { int index = 0; byte[] countArray = StringToByteArray(_fileResources.Count.ToString("G", CultureInfo.InvariantCulture)); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, "COUNT", 0, countArray, countArray.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } foreach (FileResource resource in _fileResources) { // Read in the file data int fileLength = 0; byte[] fileContent = null; using (FileStream fs = System.IO.File.OpenRead(resource.Filename)) { fileLength = (int)fs.Length; fileContent = new byte[fileLength]; fs.Read(fileContent, 0, fileLength); } // Update the resources to include this file's data string dataName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", index); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, dataName, 0, fileContent, fileLength)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } // Add this file's key to the resources string keyName = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", index); byte[] data = StringToByteArray(resource.Key); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, keyName, 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } index++; } } } } finally { if (endUpdate && !NativeMethods.EndUpdateResource(hUpdate, false)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); returnValue = false; } } return(returnValue); }
private Package GetPackageForSettings(BuildSettings settings, ProductBuilder builder, BuildResults results) { CultureInfo cultureInfoFromString = Util.GetCultureInfoFromString(settings.Culture); CultureInfo altCulture = Util.GetCultureInfoFromString(settings.FallbackCulture); Package package = null; if (builder.Product.Packages.Count == 0) { if (results != null) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.ProductCultureNotFound", new object[] { builder.Name })); } return null; } if (cultureInfoFromString != null) { package = builder.Product.Packages.Package(cultureInfoFromString.Name); if (package != null) { return package; } for (CultureInfo info3 = cultureInfoFromString.Parent; (info3 != null) && (info3 != CultureInfo.InvariantCulture); info3 = info3.Parent) { package = this.GetPackageForSettings_Helper(cultureInfoFromString, info3, builder, results, false); if (package != null) { return package; } } } if (altCulture != null) { package = this.GetPackageForSettings_Helper(cultureInfoFromString, altCulture, builder, results, true); if (package != null) { return package; } if (!altCulture.IsNeutralCulture) { package = this.GetPackageForSettings_Helper(cultureInfoFromString, altCulture.Parent, builder, results, true); if (package != null) { return package; } } } package = this.GetPackageForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo, builder, results, true); if (package != null) { return package; } if (!Util.DefaultCultureInfo.IsNeutralCulture) { package = this.GetPackageForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo.Parent, builder, results, true); if (package != null) { return package; } } if ((results != null) && (cultureInfoFromString != null)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingProductCulture", new object[] { cultureInfoFromString.Name, builder.Name, builder.Product.Packages.Item(0).Culture })); } return builder.Product.Packages.Item(0); }