Как программно изменить привязку сборки в app.config?
-
03-07-2019 - |
Вопрос
Я пытаюсь изменить элементbindingRedirect во время установки, используя класс XmlDocument и изменяя значение напрямую.Вот как выглядит мой app.config:
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
...
</sectionGroup>
</configSections>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyDll" publicKeyToken="31bfe856bd364e35"/>
<bindingRedirect oldVersion="0.7" newVersion="1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
...
</configuration>
Затем я пытаюсь использовать следующий код, чтобы изменить версию 1.0 на 2.0.
private void SetRuntimeBinding(string path, string value)
{
XmlDocument xml = new XmlDocument();
xml.Load(Path.Combine(path, "MyApp.exe.config"));
XmlNode root = xml.DocumentElement;
if (root == null)
{
return;
}
XmlNode node = root.SelectSingleNode("/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect/@newVersion");
if (node == null)
{
throw (new Exception("not found"));
}
node.Value = value;
xml.Save(Path.Combine(path, "MyApp.exe.config"));
}
Однако он выдает исключение «не найдено».Если я верну путь до /configuration/runtime, он сработает.Однако как только я добавляю сборкуBinding, узел не находит.Возможно, это как-то связано с xmlns?Есть идеи, как я могу это изменить?ConfigurationManager также не имеет доступа к этому разделу.
Решение
Я нашел то, что мне было нужно.XmlNamespaceManager необходим, поскольку узел сборкиBinding содержит атрибут xmlns.Я изменил код, чтобы использовать это, и он работает:
private void SetRuntimeBinding(string path, string value)
{
XmlDocument doc = new XmlDocument();
try
{
doc.Load(Path.Combine(path, "MyApp.exe.config"));
}
catch (FileNotFoundException)
{
return;
}
XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("bindings", "urn:schemas-microsoft-com:asm.v1");
XmlNode root = doc.DocumentElement;
XmlNode node = root.SelectSingleNode("//bindings:bindingRedirect", manager);
if (node == null)
{
throw (new Exception("Invalid Configuration File"));
}
node = node.SelectSingleNode("@newVersion");
if (node == null)
{
throw (new Exception("Invalid Configuration File"));
}
node.Value = value;
doc.Save(Path.Combine(path, "MyApp.exe.config"));
}
Другие советы
Похоже, у вас теперь работает настройка файла конфигурации, но я подумал, что вас все еще может заинтересовать, как настроить перенаправление привязки во время выполнения.Ключевым моментом является использование AppDomain.AssemblyResolve событие, подробности в этот ответ.Я предпочитаю это использованию файла конфигурации, потому что мое сравнение номеров версий может быть немного более сложным, и мне не придется настраивать файл конфигурации во время каждой сборки.
Я думаю, что правильный синтаксис Xpath:
/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect@newVersion
(у вас слишком много косых черт).
Или, если это не сработает, вы можете выбрать элементbindingRedirect (используя SelectSingleNode):
/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect
Затем измените атрибут newVersion этого элемента.