views:

2246

answers:

5

I am trying to change the bindingRedirect element at install time by using the XmlDocument class and modifying the value directly. Here is what my app.config looks like:


<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>

I then try to use the following code to change 1.0 to 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"));

    }

However, it throws the 'not found' exception. If I back the path up to /configuration/runtime it works. However once I add assemblyBinding, it does not find the node. Possibly this has something to do with the xmlns? Any idea how I can modify this? ConfigurationManager also does not have access to this section.

A: 

Modifying Configuration Settings at Runtime By UsualDosage

This article will demonstrate how to add, delete, and update key value pairs in an App.config file.

http://www.codeproject.com/KB/cs/modconfigruntime.aspx

MaSuGaNa
Not helpful. I already know how to modify it programatically at runtime. My problem is that it works for other areas, just not for assemblyBinding element.
esac
A: 

I think the right Xpath syntax is:

/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect@newVersion

(you have a slash too many).

Or if this doesn't work you could select the bindingRedirect element (using SelectSingleNode):

/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect

Then modify the attribute newVersion of this element.

Joe
Already been down this path, it complains of invalid token with bindingRedirect@newVersion. Second case, it complains that it could not find the path specified.
esac
+3  A: 

I found what I needed. The XmlNamespaceManager is required as the assemblyBinding node contains the xmlns attribute. I modified the code to use this and it works:

    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"));
    }
esac
Just a note, I throw exceptions as this is part of an Setup Project and that is how the installer is notified of any errors. It would be better to have the method return true or false if the modification was made.
esac
A: 

Sounds like you've got your configuration file tweak working now, but I thought you might still be interested in how to adjust binding redirects at run time. The key is to use the AppDomain.AssemblyResolve event, and the details are in this answer. I prefer it over using the configuration file, because my version number comparison can be a bit more sophisticated and I don't have to tweak the configuration file during every build.

Don Kirkby
A: 

awesome thread, saved me a ton of time.

chrisjlong