2009-04-30 13 views
8

Próbuję zmienić element bindingRedirect w czasie instalacji, używając klasy XmlDocument i modyfikując wartość bezpośrednio. Oto co mój app.config wygląda następująco:Jak programowo modyfikować assemblyBinding w 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 spróbuj użyć następującego kodu zmienić 1,0 do 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")); 

    } 

jednak rzuca 'nie odnaleziono wyjątek. Jeśli cofnę ścieżkę do/configuration/runtime, to działa. Jednak po dodaniu assemblyBinding nie znajduje węzła. Być może ma to coś wspólnego z xmlns? Masz pomysł, jak mogę to zmienić? ConfigurationManager również nie ma dostępu do tej sekcji.

Odpowiedz

8

Znalazłem to, czego potrzebowałem. XmlNamespaceManager jest wymagany, ponieważ węzeł assemblyBinding zawiera atrybut xmlns. I zmodyfikowany kod, aby korzystać z tej i to działa:

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

Po prostu notka, zgłaszam wyjątki, ponieważ jest to część Projektu Instalatora i tak instalator jest powiadamiany o wszelkich błędach. Byłoby lepiej, gdyby ta metoda zwróciła wartość true lub false, jeśli modyfikacja została wykonana. – esac

-1

myślę prawo składnia XPath:

/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect @ Newversion

(trzeba ukośnik zbyt wiele).

A jeśli to nie zadziała można wybrać element bindingRedirect (używając SelectSingleNode):

/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect

Następnie zmodyfikować atrybut Newversion tego elementu.

+0

Już na tej ścieżce, skarży się na nieprawidłowy token z bindingRedirect @ newVersion. W drugim przypadku skarży się, że nie może znaleźć określonej ścieżki. – esac

8

Brzmi jak masz plik konfiguracyjny dostrojenia pracy teraz, ale pomyślałem, że może nadal być zainteresowany w jaki sposób dostosować wiążących przekierowań w czasie wykonywania. Kluczem jest użycie zdarzenia AppDomain.AssemblyResolve, a szczegóły są podane w this answer. Wolę go od używania pliku konfiguracyjnego, ponieważ moje porównanie numerów wersji może być nieco bardziej wyrafinowane i nie muszę modyfikować pliku konfiguracyjnego podczas każdej kompilacji.

+0

Koleś! To powinna być zaakceptowana odpowiedź. – Jupaol

+3

Działa to, jeśli początkowo nie powiedzie się ładowanie zespołu. Jeśli jednak twoja aplikacja pomyślnie załaduje zestaw _wrong_, AssemblyResolve nigdy się nie uruchomi. Tak więc jedyną opcją w tym przypadku jest modyfikacja pliku app.config. – Phil

+0

Chciałbym wycofać swój głos. To faktycznie nie działa, jeśli powiązanie jest ustawione, jak z .NET 4.6.1. Nadal występują awarie powiązania zespołu. – Nuzzolilo

Powiązane problemy