public static void Install(String machineConfigPath, String patchFileName) { ConfigXmlDocument machineConfig = new ConfigXmlDocument(); machineConfig.PreserveWhitespace = true; machineConfig.Load(machineConfigPath); XmlDocument patch = new XmlDocument(); patch.PreserveWhitespace = true; patch.Load(patchFileName); // Remove original <result type=""> node, replace by // comment. Only one <result> node allowed in machine.config. String resultPath = "/configuration/system.web/browserCaps/result"; String browserCapsPath = "/configuration/system.web/browserCaps"; XmlNode resultNode = machineConfig.SelectSingleNode(resultPath); XmlNode browserCapsNode = machineConfig.SelectSingleNode(browserCapsPath); XmlNode patchResultNode = patch.SelectSingleNode(resultPath); XmlNode patchBrowserCapsNode = patch.SelectSingleNode(browserCapsPath); XmlNode patchResultNodeClone = machineConfig.ImportNode(patchResultNode, true); patchBrowserCapsNode.RemoveChild(patchResultNode); ArrayList browserCapsLeadingWhitespace = new ArrayList(); foreach (XmlNode child in browserCapsNode.ChildNodes) { if (child.NodeType == XmlNodeType.Whitespace) { browserCapsLeadingWhitespace.Add(child); } else { break; } } StringBuilder commentText = new StringBuilder(); if (resultNode != null) { XmlTextWriter commentWriter = new XmlTextWriter(new StringWriter(commentText)); resultNode.WriteTo(commentWriter); browserCapsNode.RemoveChild(resultNode); } MergePrepend(machineConfig, patch, "/configuration/system.web/httpModules"); MergePrepend(machineConfig, patch, "/configuration/configSections/sectionGroup[@name='system.web']"); MergePrepend(machineConfig, patch, "/configuration/system.web/compilation/assemblies"); Merge(machineConfig, patch, "/configuration/system.web/browserCaps"); Insert(machineConfig, patch, "/configuration/system.web", "mobileControls"); Insert(machineConfig, patch, "/configuration/system.web", "deviceFilters"); // Prepend these nodes (in reverse order) so that they occur // before any other children. if (resultNode != null) { PrependComment(machineConfig, browserCapsNode, _removedEltEndComment); PrependComment(machineConfig, browserCapsNode, commentText.ToString()); PrependComment(machineConfig, browserCapsNode, _removedEltBeginComment); } PrependComment(machineConfig, browserCapsNode, _endComment); browserCapsNode.PrependChild(patchResultNodeClone); // Clone formatting for inserted node. foreach (XmlNode child in browserCapsLeadingWhitespace) { browserCapsNode.PrependChild(child.CloneNode(false /* deep */)); } PrependComment(machineConfig, browserCapsNode, _beginComment); // Clone formatting for uninstall. foreach (XmlNode child in browserCapsLeadingWhitespace) { browserCapsNode.PrependChild(child.CloneNode(false /* deep */)); browserCapsNode.RemoveChild(child); } RemoveExtraWhitespace(machineConfig); StreamWriter s = new StreamWriter(machineConfigPath); XmlIndentAttributeTextWriter writer = new XmlIndentAttributeTextWriter(s); writer.Formatting = Formatting.Indented; writer.Indentation = 4; machineConfig.Save(writer); writer.Flush(); writer.Close(); }