根据this issue我试图创建一个方法来检查machine.config文件的当前状态(以查看是否存在运行时更改),如果没有,则更新或删除它们。我的current solution正在使用XmlDocument来编写,但是我在下次运行时检查现有元素的尝试总是返回null或false:
XmlDocument doc = new XmlDocument();
doc.Load(file);
Console.WriteLine(null == doc.SelectSingleNode("/configuration"))); //true
Console.WriteLine(null ==
doc.SelectSingleNode("/configuration/runtime"))); //true
Console.WriteLine(null ==
doc.SelectSingleNode("/configuration/runtime/assemblyBinding"))); //false
我的第二次尝试是使用Linq to XML来查找数据,但不知道它是如何工作的,我无法得到任何结果:
XDocument doc = XDocument.Load(RuntimeEnvironment.SystemConfigurationFile);
var data = from item in root.Descendants("assemblyIdentity") select el;
var foo = doc.Descendants("assemblyIdentity")
.Attributes("publicKeyToken")
.Where(x => x.Value == @"b03f5f7f11d50a3a")
.ToList();
Console.WriteLine(foo.Count); //shows 0
我的第三次尝试是使用ConfigurationManager class来读取文件,但是我能够打开文件并阅读它,我只能抓住运行时元素,而不是任何包含的信息。我最多能够检查原始xml数据:
Configuration machineConfig =
ConfigurationManager.OpenMachineConfiguration();
ConfigurationFileMap configFile =
new ConfigurationFileMap(machineConfig.FilePath);
Configuration config =
ConfigurationManager.OpenMappedMachineConfiguration(
configFile);
ConfigurationSectionCollection sections =
config.Sections;
ConfigurationSection runtime = config.GetSection("runtime");
Console.WriteLine(runtime.SectionInformation.GetRawXml()
.Contains("System.Runtime")); //true
由于我没有看到对运行时元素的任何内置支持(就像AppSettings那样)我尝试创建custom configuration section(view that code here),但一直无法用它做任何事情:
RuntimeSection runtimeSection = (RuntimeSection)config.GetSection("runtime");
Console.WriteLine(runtimeSection.SectionInformation.GetRawXml()); //nothing
那么,话虽如此,我如何检查machine.config文件以确保元素更改尚未到位?
答案 0 :(得分:0)
在与同事交谈后,我们能够找到解决方案。为了访问现有元素,我们必须设置命名空间管理器:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bind", "urn:schemas-microsoft-com:asm.v1");
从那里开始使用XPath抓取元素非常简单,你只需要包含命名空间:
doc.SelectSingleNode("//bind:assemblyBinding", nsmgr);
如果您希望一次性添加元素,则子元素不需要附加名称空间(因为它显然知道它们都在同一名称空间下)。但是,如果您要添加到已经部分存在的文件中,最好明确包含命名空间;否则它会看到一个名称空间存在并假设您缺少名称空间是有意的,添加一个额外的空白名称空间属性,可能导致事情不起作用()。
请记住,创建元素需要命名空间为字符串:
ParentElement.AppendChild(xmlDoc.CreateElement("subElement",
nsmgr.LookupNamespace("bind"))
我的最终目标是在安装过程中使用它来更新machine.config文件(如果有必要)(以避免重复)。如需完整解决方案,请随意look here。