8

Tôi đang viết một ứng dụng WinForms/C#/.NET 3.5 thử nghiệm cho hệ thống mà chúng tôi đang phát triển và chúng tôi cần phải chuyển đổi giữa các tệp .config trong thời gian chạy, nhưng điều này đang diễn ra là một cơn ác mộng.Thay đổi App.config tại Thời gian chạy

Đây là cảnh: ứng dụng WinForms nhằm mục đích thử nghiệm một WebApp, được chia thành 5 hệ thống phụ. Quá trình kiểm tra làm việc với các thư được gửi giữa các hệ thống con và để quá trình này thành công, mỗi hệ thống con phải có tệp .config riêng.

Đối với ứng dụng thử nghiệm của tôi, tôi đã viết 5 tệp cấu hình riêng biệt. Tôi muốn tôi có thể chuyển đổi giữa 5 tệp này trong thời gian chạy, nhưng vấn đề là: Tôi có thể lập trình chỉnh sửa tệp .config rất nhiều lần, nhưng những thay đổi này sẽ chỉ có hiệu lực một lần. Tôi đã tìm kiếm một thời gian dài cho một hình thức để giải quyết vấn đề này nhưng tôi vẫn không thành công.

Tôi biết định nghĩa sự cố có thể hơi khó hiểu nhưng tôi thực sự đánh giá cao nếu có ai đó giúp tôi.

Cảm ơn trước!

--- CẬP NHẬT 01-06-10 ---

Có điều tôi chưa đề cập trước đây. Ban đầu, hệ thống của chúng tôi là một ứng dụng web với các cuộc gọi WCF giữa mỗi hệ thống con. Vì lý do kiểm tra hiệu năng (chúng tôi đang sử dụng ANTS 4), chúng tôi phải tạo một bản sao cục bộ của các hội đồng và tham khảo chúng từ dự án thử nghiệm. Nghe có vẻ hơi sai, nhưng chúng tôi không thể tìm ra cách thỏa mãn để đo hiệu năng của một ứng dụng từ xa.

--- End Update ---

Đây là những gì tôi đang làm:

public void UpdateAppSettings(string key, string value) 
{ 
    XmlDocument xmlDoc = XmlDocument.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 

    foreach (XmlElement item in xmlDoc.DocumentElement) 
    { 
     foreach (XmlNode node in item.ChildNodes) 
     { 
      if (node.Name == key) 
      { 
       node.Attributes[0].Value = value; 
       break; 
      } 
     } 
    } 

    xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 

    System.Configuration.ConfigurationManager.RefreshSection("section/subSection");  
} 
+0

dup/related? http://stackoverflow.com/questions/1542171/change-app-config-at-runtime – Hogan

+0

Tôi đã thử các aproaches này ... vấn đề là, thẻ tôi đang thay đổi nằm ngoài số . Tôi cũng đã thử tạo các AppDomain mới và thiết lập các tệp .config khác nhau cho chúng, nhưng nó cũng không hoạt động. –

Trả lời

3

CẬP NHẬT

Các giải pháp dưới đây không làm việc vì XmlDocument không vứt bỏ và có vẻ như một số phiên bản của .net không đóng đúng khi đưa ra một đường dẫn tập tin. Các giải pháp (ví dụ mã trong liên kết) là để mở một dòng mà sẽ làm một vứt bỏ và vượt qua dòng đó vào chức năng tiết kiệm.

Giải pháp được hiển thị tại đây.http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


Cũ thứ dưới đây

Hãy thử điều này:

Lưu ý, tôi đã thay đổi để xpath, nhưng nó đã được một thời gian vì vậy tôi có thể đã nhận được xpath sai, nhưng trong mọi trường hợp bạn nên sử dụng xpath và không đi bộ cây. Như bạn có thể thấy nó rõ ràng hơn nhiều.

Điểm quan trọng là tuyên bố using sẽ là dispose(), điều mà tôi nghĩ là sự cố của bạn.

Hãy cho tôi biết, chúc bạn may mắn.

public void UpdateAppSettings(string key, string value) 
    { 
    using (XmlDocument xmlDoc = new XmlDocument()) 
    { 
     xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 
     xmlDoc.DocumentElement.FirstChild.SelectSingleNode("descendant::"+key).Attributes[0].Value = value; 
     xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 
    } 
    System.Configuration.ConfigurationManager.RefreshSection("section/subSection"); 
    } 
+1

Đó là kinda có ý nghĩa, vấn đề là XmlDocument không thực hiện IDisposable, vì vậy nó không thể sử dụng phạm vi "sử dụng". –

+0

Có bạn đúng ... xem nhận xét của tôi ở trên. – Hogan

+0

Vâng, tôi có một chút đoán rằng đây không phải là trường hợp. Tôi đang sử dụng framework .NET 3.5. Bên cạnh đó, tôi nghĩ rằng nếu các dòng tập tin vẫn còn mở, bởi lần thứ hai tôi sẽ cố gắng để viết vào tập tin xml, tôi sẽ nhận được một ngoại lệ ... nhưng cảm ơn anyway. –

2

tôi đoán là bạn đang không thực sự đóng tập tin xử lý lần đầu tiên nên các cửa sổ không "nhìn thấy "bạn thực hiện các thay đổi sau này.

Đề xuất của tôi là sử dụng lệnh gọi API tới IIS và tắt ứng dụng web (và nhóm), thực hiện thay đổi, bật ứng dụng web. Bằng cách này bạn chắc chắn nó sẽ đọc lại tập tin và có một môi trường "sạch" cho mỗi bài kiểm tra.

+0

Tôi đã cập nhật câu hỏi với một số chi tiết. Về cơ bản, trong ngữ cảnh này (kiểm thử hiệu năng) chúng ta không sử dụng IIS, các assembly đang được tham chiếu cục bộ. Tôi đang sử dụng thư viện Xml để ghi vào tập tin .config. Trong quá trình thực hiện, tôi có thể thấy rằng tệp đang được viết và thay đổi. –

1

Giả sử rằng tệp xử lý tệp cấu hình bị đóng sau khi tệp cấu hình đã được đọc và xử lý, tôi sẽ gửi thư đến ứng dụng để yêu cầu đọc lại tệp cấu hình sau khi bạn đã cập nhật tệp. Nếu phương pháp này không hoạt động, thì tôi nghi ngờ (như Hogan đề nghị) rằng việc xử lý tập tin không được đóng lại. Bạn nhận được mã lỗi nào từ việc mở tệp, đọc và đóng các cuộc gọi hệ thống? (Sử dụng perror để báo cáo thông báo lỗi)

+1

Cách tiếp cận này thú vị, nhưng bạn có thể cho tôi một số bước về cách gửi tin nhắn này đến ứng dụng không? Tôi đã thử gọi ConfigurationManager.RefreshSection() nhưng nó không hoạt động. –

+1

@born to hula: Làm thế nào để bạn thay đổi cấu hình @ runtime? Tôi muốn sử dụng phương pháp tương tự để ứng dụng đọc lại tập tin cấu hình. Bạn đang sử dụng ngôn ngữ và hệ điều hành nào? Các tin nhắn được gửi đến ứng dụng trong quá trình thử nghiệm là gì? Liệu đầu vào cho ứng dụng đến từ một trang web? Trả lời những câu hỏi này sẽ đưa ra một số manh mối về cách tiếp cận tốt nhất cho tình huống của bạn. –

+0

Tôi đang sử dụng XmlDocument để thay đổi tệp .config (tham khảo câu hỏi được cập nhật). Nhưng, bất kể bao nhiêu lần tôi thay đổi nó, những thay đổi sẽ chỉ được phản ánh một lần trên bối cảnh thực thi. Tôi đang sử dụng C# và Windows XP. Đầu vào từ ứng dụng đến trực tiếp từ biểu mẫu. Về cơ bản, đầu vào chính là một thông điệp, từ đó một loạt các đối tượng được tạo ra. –

24

Tôi hiểu đây là một chủ đề cũ nhưng tôi không thể đưa các phương thức được liệt kê vào hoạt động. Đây là một phiên bản đơn giản của phương pháp UpdateAppSettings (sử dụng .NET 4.0):

private void UpdateAppSettings(string theKey, string theValue) 
     { 
      Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
      if (ConfigurationManager.AppSettings.AllKeys.Contains(theKey)) 
      { 
       configuration.AppSettings.Settings[theKey].Value = theValue; 
      } 

      configuration.Save(ConfigurationSaveMode.Modified); 

      ConfigurationManager.RefreshSection("appSettings"); 
     } 

Khá dễ đọc và tránh được việc phải đi qua app.config sử dụng XPath hoặc tương tự. Lưu ý: Mã ở trên được lấy cảm hứng từ this đoạn mã trên MSDN.

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