2009-04-30 35 views
8

Tôi đang cố gắng thay đổi phần tử bindingRedirect lúc cài đặt bằng cách sử dụng lớp XmlDocument và sửa đổi giá trị trực tiếp. Đây là những gì app.config của tôi trông giống như:Làm thế nào để sửa đổi programBinding trong 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> 
 

Sau đó tôi cố gắng sử dụng đoạn mã sau để thay đổi 1.0 đến 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")); 

    } 

Tuy nhiên, nó ném ngoại lệ 'không tìm thấy'. Nếu tôi trở lại đường dẫn đến/cấu hình/thời gian chạy nó hoạt động. Tuy nhiên một khi tôi thêm assemblyBinding, nó không tìm thấy nút. Có thể điều này có liên quan đến xmlns? Bất kỳ ý tưởng làm thế nào tôi có thể sửa đổi điều này? ConfigurationManager cũng không có quyền truy cập vào phần này.

Trả lời

8

Tôi đã tìm thấy những gì tôi cần. XmlNamespaceManager là bắt buộc vì nút assemblyBinding chứa thuộc tính xmlns. Tôi đã sửa đổi mã này để sử dụng và nó hoạt động:

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

Chỉ cần lưu ý, tôi ném ngoại lệ vì đây là một phần của Dự án Thiết lập và đó là cách trình cài đặt được thông báo về bất kỳ lỗi nào. Nó sẽ là tốt hơn để có phương pháp trả về true hoặc false nếu sửa đổi đã được thực hiện. – esac

-1

Tôi nghĩ rằng cú pháp XPath đúng là:

/cấu hình/thời gian chạy/assemblyBinding/dependentAssembly/bindingRedirect @ newVersion

(bạn có một dấu gạch chéo quá nhiều).

Hoặc nếu điều này không làm việc bạn có thể chọn phần tử bindingRedirect (sử dụng SelectSingleNode):

/cấu hình/thời gian chạy/assemblyBinding/dependentAssembly/bindingRedirect

Sau đó sửa đổi các thuộc tính newVersion của nguyên tố này.

+0

Đã xuống đường dẫn này, nó khiếu nại mã thông báo không hợp lệ với bindingRedirect @ newVersion. Trường hợp thứ hai, nó phàn nàn rằng nó không thể tìm thấy đường dẫn được chỉ định. – esac

8

Có vẻ như bạn đã có tinh chỉnh tệp cấu hình, nhưng tôi nghĩ bạn vẫn có thể quan tâm đến cách điều chỉnh chuyển hướng ràng buộc trong thời gian chạy. Điều quan trọng là sử dụng sự kiện AppDomain.AssemblyResolve và các chi tiết có trong this answer. Tôi thích nó hơn bằng cách sử dụng tập tin cấu hình, bởi vì so sánh số phiên bản của tôi có thể phức tạp hơn một chút và tôi không phải tinh chỉnh tệp cấu hình trong mỗi lần xây dựng.

+0

Dude! Đây sẽ là câu trả lời được chấp nhận. – Jupaol

+3

Điều này hoạt động, nếu tải lắp ráp ban đầu không thành công. Tuy nhiên, nếu ứng dụng của bạn quản lý để tải thành công cụm _wrong_, AssemblyResolve sẽ không bao giờ cháy. Vì vậy, lựa chọn duy nhất trong trường hợp đó là sửa đổi app.config. – Phil

+0

Ước gì tôi có thể rút lại phiếu bầu của mình. Điều này thực sự không hoạt động nếu ràng buộc được thiết lập, như của .NET 4.6.1. Vẫn nhận được thất bại ràng buộc lắp ráp. – Nuzzolilo

Các vấn đề liên quan