2009-04-30 18 views
8

XmlDocumentクラスを使用して値を直接変更することで、インストール時にbindingRedirect要素を変更しようとしています。ここに私はapp.configは、次のようになります。app.configのassemblyBindingをプログラムで変更する方法はありますか?

 

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

私はその後、1.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")); 

    } 

2.0を変更するには、次のコードを使用しようしかし、それは「が見つかりません」例外がスローされます。私がパスを/ configuration/runtimeに戻すと、それは動作します。しかし、assemblyBindingを追加するとノードが見つかりません。おそらく、これはxmlnsと関係がありますか?どのように私はこれを変更することができる任意のアイデア? ConfigurationManagerもこのセクションにアクセスできません。

答えて

8

私は必要なものを見つけました。 assemblyBindingノードにxmlns属性が含まれているため、XmlNamespaceManagerが必要です。私はこれを使用するようにコードを修正し、それが動作します:あなたがあなたの設定ファイルは、現在取り組んで微調整持っているよう

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

これはセットアッププロジェクトの一部であり、インストーラにエラーが通知されるため、例外をスローします。修正が行われた場合、メソッドにtrueまたはfalseが返されるようにする方がよいでしょう。 – esac

-1

私は右のXPath構文があると思う:

/設定/実行/ assemblyBinding/dependentAssembly/bindingRedirect @ NEWVERSION

(あなたはあまりにも多くのスラッシュを持っています)。

それともこれが動作しない場合は、(SELECTSINGLENODEを使用して)bindingRedirect要素を選択することができます:

/設定/実行/ assemblyBinding/dependentAssembly/bindingRedirect

次に、この要素の属性NEWVERSIONを変更します。

+0

既にこのパスがダウンしていると、bindingRedirect @ newVersionで無効なトークンが発生しています。 2番目のケースでは、指定されたパスが見つからないと不平を言う。 – esac

8

が聞こえるが、私はあなたがまだ実行時バインディングリダイレクトを調整する方法に興味を持つかもしれないと思いました。キーはAppDomain.AssemblyResolveイベントを使用することで、詳細はthis answerです。私はバージョン番号の比較が少し洗練されている可能性があり、すべてのビルド中に構成ファイルを微調整する必要がないので、構成ファイルを使用することをお勧めします。

+0

おい!これは受け入れられた答えでなければなりません。 – Jupaol

+3

アセンブリロードが最初に失敗した場合、これは機能します。しかし、アプリケーションが_wrong_アセンブリを正常にロードすることを管理する場合、AssemblyResolveは決して起動しません。その場合、唯一のオプションはapp.configを変更することです。 – Phil

+0

欲しい私の投票を撤回することができます。これは、.NET 4.6.1のように、バインディングが設定されている場合は実際には機能しません。それでもアセンブリのバインディングエラーが発生します。 – Nuzzolilo

関連する問題