简体   繁体   English

如何以编程方式修改app.config中的assemblyBinding?

[英]How to programmatically modify assemblyBinding in app.config?

I am trying to change the bindingRedirect element at install time by using the XmlDocument class and modifying the value directly. 我试图通过使用XmlDocument类并直接修改值来在安装时更改bindingRedirect元素。 Here is what my app.config looks like: 这是我的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>

I then try to use the following code to change 1.0 to 2.0 然后我尝试使用以下代码将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"));
}

However, it throws the 'not found' exception. 但是,它会引发“未找到”的异常。 If I back the path up to /configuration/runtime it works. 如果我将路径备份到/ configuration / runtime它就可以了。 However once I add assemblyBinding, it does not find the node. 但是,一旦我添加了assemblyBinding,它就找不到该节点。 Possibly this has something to do with the xmlns? 可能这与xmlns有关吗? Any idea how I can modify this? 知道怎么修改这个吗? ConfigurationManager also does not have access to this section. ConfigurationManager也无权访问此部分。

I found what I needed. 我找到了我需要的东西。 The XmlNamespaceManager is required as the assemblyBinding node contains the xmlns attribute. 由于assemblyBinding节点包含xmlns属性,因此需要XmlNamespaceManager。 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"));
    }

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 . 关键是使用AppDomain.AssemblyResolve事件,详细信息在此答案中 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. 我比使用配置文件更喜欢它,因为我的版本号比较可能更复杂,我不必在每次构建期间调整配置文件。

I think the right Xpath syntax is: 我认为正确的Xpath语法是:

/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect@newVersion /配置/运行/ assemblyBinding / dependentAssembly / bindingRedirect @ NEWVERSION

(you have a slash too many). (你的斜线太多了)。

Or if this doesn't work you could select the bindingRedirect element (using SelectSingleNode): 或者,如果这不起作用,您可以选择bindingRedirect元素(使用SelectSingleNode):

/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect /配置/运行/ assemblyBinding / dependentAssembly / bindingRedirect

Then modify the attribute newVersion of this element. 然后修改此元素的属性newVersion。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM