2009-04-30 7 views
8

Ich versuche, das bindingRedirect-Element zur Installationszeit zu ändern, indem ich die XmlDocument-Klasse verwende und den Wert direkt ändere. Hier ist, was meine app.config wie folgt aussieht:Wie programmierst du assemblyBinding in 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> 
 

ich dann versuchen, den folgenden Code zu 1.0 verwenden zu 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")); 

    } 

jedoch zu ändern, ist es die ‚nicht gefunden‘ Ausnahme auslöst. Wenn ich den Pfad bis zu/configuration/runtime zurücksetze, funktioniert es. Sobald ich jedoch assemblyBinding hinzufüge, wird der Knoten nicht gefunden. Möglicherweise hat das etwas mit den xmlns zu tun? Irgendeine Idee, wie ich das ändern kann? ConfigurationManager hat auch keinen Zugriff auf diesen Abschnitt.

Antwort

8

Ich fand, was ich brauchte. Der XmlNamespaceManager wird benötigt, da der assemblyBinding-Knoten das xmlns-Attribut enthält. Ich änderte den Code dieses zu verwenden und es funktioniert:

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

Nur eine Anmerkung, ich werfe Ausnahmen aus, da dies Teil eines Setup-Projekts ist und der Installer über Fehler benachrichtigt wird. Es wäre besser, wenn die Methode wahr oder falsch zurückgibt, wenn die Änderung vorgenommen wurde. – esac

-1

glaube ich die richtige XPath-Syntax ist:

/configuration/runtime/assembly/dependentAssembly/bindingRedirect @ newVersion

(Sie haben einen Schrägstrich zu viele).

Oder wenn dies nicht funktioniert, könnte das bindingRedirect Element (mit SelectSingleNode) wählen:

/configuration/runtime/assembly/dependentAssembly/bindingRedirect

Dann das Attribut newVersion dieses Elements ändern.

+0

Bereits auf diesem Pfad, klagt es über ungültiges Token mit bindingRedirect @ newVersion. Zweiter Fall, beschwert sich, dass es den angegebenen Pfad nicht finden konnte. – esac

8

Klingt wie Sie Ihre Konfigurationsdatei zwicken arbeiten jetzt haben, aber ich dachte, dass Sie immer noch interessiert sein könnte, wie Bindung Umleitungen zur Laufzeit einzustellen. Der Schlüssel ist, das Ereignis AppDomain.AssemblyResolve zu verwenden, und die Details sind in this answer. Ich bevorzuge es gegenüber der Verwendung der Konfigurationsdatei, weil mein Vergleich der Versionsnummer ein bisschen ausgeklügelter sein kann und ich die Konfigurationsdatei nicht bei jedem Build optimieren muss.

+0

Alter! Dies sollte die akzeptierte Antwort sein. – Jupaol

+3

Dies funktioniert, wenn die Montage zunächst fehlschlägt. Wenn es Ihrer App jedoch gelingt, die _wrong_ Assembly erfolgreich zu laden, wird AssemblyResolve nie ausgelöst. In diesem Fall besteht die einzige Möglichkeit darin, die Datei app.config zu ändern. – Phil

+0

Ich wünschte, ich könnte meine Stimme zurückziehen. Dies funktioniert nicht, wenn die Bindung festgelegt ist, wie von .NET 4.6.1. Erhalten Sie immer noch Assembly-Bindungsfehler. – Nuzzolilo