Pregunta

Estoy intentando cambiar el elemento bindingRedirect en el momento de la instalación utilizando la clase XmlDocument y modificando el valor directamente. Aquí es cómo se ve mi 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>

Luego trato de usar el siguiente código para cambiar 1.0 a 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"));
}

Sin embargo, lanza la excepción 'no encontrado'. Si respaldo la ruta hasta / configuration / runtime, funcionará. Sin embargo, una vez que agrego AssemblyBinding, no encuentra el nodo. Posiblemente esto tiene algo que ver con los xmlns? ¿Alguna idea de cómo puedo modificar esto? ConfigurationManager tampoco tiene acceso a esta sección.

¿Fue útil?

Solución

Encontré lo que necesitaba. Se requiere XmlNamespaceManager ya que el nodo assemblyBinding contiene el atributo xmlns. He modificado el código para usar esto y funciona:

    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"));
    }

Otros consejos

Parece que tienes tu ajuste de archivo de configuración funcionando ahora, pero pensé que todavía podrías estar interesado en cómo ajustar las redirecciones de enlace en el tiempo de ejecución. La clave es usar el AppDomain.AssemblyResolve event y los detalles están en esta respuesta . Prefiero usar el archivo de configuración, porque mi comparación de número de versión puede ser un poco más sofisticada y no tengo que modificar el archivo de configuración durante cada compilación.

Creo que la sintaxis Xpath correcta es:

/ configuration / runtime / assemblyBinding / dependenciaAssembly / bindingRedirect @ newVersion

(tienes una barra demasiado).

O si esto no funciona, puede seleccionar el elemento bindingRedirect (utilizando SelectSingleNode):

/ configuration / runtime / assemblyBinding / dependenciaAssembly / bindingRedirect

Luego modifique el atributo newVersion de este elemento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top