8

Ich schreibe eine WinForms/C#/.NET 3.5-Testanwendung für das System, das wir entwickeln, und wir mussten zur Laufzeit zwischen den .config-Dateien wechseln ein Albtraum sein.Ändern von App.config zur Laufzeit

Hier ist die Szene: Die WinForms-Anwendung soll eine WebApp testen, die in 5 Subsysteme unterteilt ist. Der Testprozess funktioniert mit Nachrichten, die zwischen den Subsystemen gesendet werden, und damit dieser Prozess erfolgreich ist, muss jedes Subsystem seine eigene .config-Datei haben.

Für meine Testanwendung habe ich 5 separate Konfigurationsdateien geschrieben. Ich wünschte, ich könnte während der Laufzeit zwischen diesen 5 Dateien wechseln, aber das Problem ist: Ich kann die Anwendung .config Datei mehrmals bearbeiten, aber diese Änderungen werden nur einmal wirksam. Ich habe lange nach einem Formular gesucht, um dieses Problem anzugehen, aber ich war immer noch nicht erfolgreich.

Ich weiß, dass die Problemdefinition ein bisschen verwirrend sein kann, aber ich würde es wirklich schätzen, wenn mir jemand half.

Vielen Dank im Voraus!

--- UPDATE 01-06-10 ---

Da ist etwas, das ich vorher nicht erwähnt hat. Ursprünglich ist unser System eine Webanwendung mit WCF-Aufrufen zwischen jedem Subsystem. Aus Gründen der Leistungstests (wir verwenden ANTS 4) mussten wir eine lokale Kopie der Assemblys erstellen und sie aus dem Testprojekt referenzieren. Es mag ein bisschen falsch klingen, aber wir konnten keine zufriedenstellende Möglichkeit finden, die Leistung einer Remote-Anwendung zu messen. Aktualisieren

--- Ende ---

Hier ist, was ich tue:

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/verwandt? http://StackOverflow.com/Questions/1542171/change-app-config-at-Runtime – Hogan

+0

Ich habe diese Ansätze schon probiert ... das Problem ist, das Tag, das ich ändern werde, ist außerhalb . Ich habe auch versucht, neue AppDomains zu erstellen und verschiedene .config-Dateien auf sie zu setzen, aber es hat auch nicht funktioniert. –

Antwort

3

UPDATE

Die Lösung unten nicht funktioniert, da XmlDocument verfügen nicht und es scheint, einige Versionen von .net schließen nicht richtig, wenn Sie einen Dateipfad angegeben. Die Lösung (Beispielcode in der Verknüpfung) besteht darin, einen Stream zu öffnen, der eine Entsorgung durchführt und diesen Stream an die Speicherfunktion weiterleitet.

Eine Lösung wird hier gezeigt.http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


Alte Sachen unten

Try this:

Hinweis, ich XPath geändert, aber es ist eine Weile her, so könnte ich die XPath falsch bekommen haben, aber auf jeden Fall Sie sollten Xpath verwenden und nicht den Baum gehen. Wie Sie sehen können, ist es viel klarer.

Der wichtige Punkt ist die using Aussage, die dispose(), die ich denke, war dein Problem.

Lassen Sie mich wissen, viel Glück.

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

Das ist sinnvoll, das Problem ist, XmlDocument implementiert IDisposable nicht, so dass es nicht möglich ist, den Bereich "verwenden" zu verwenden. –

+0

Ja, Sie haben Recht ... siehe meine Kommentare oben. – Hogan

+0

Nun, ich habe eine kleine Vermutung, dass dies nicht der Fall ist. Ich benutze Framework .NET 3.5. Außerdem denke ich, wenn der Dateistrom noch offen ist, würde ich beim zweiten Mal, wenn ich versuche, in die XML-Datei zu schreiben, eine Ausnahme bekommen ... aber trotzdem danke. –

2

Meine Vermutung ist, dass Sie nicht wirklich das erste Mal die Datei Griff Schließen so Fenster „nicht sehen "Sie machen die späteren Änderungen.

Meine Vorschläge bestehen darin, einen API-Aufruf für IIS zu verwenden und die Webanwendung (und den Pool) zu deaktivieren, die Änderung vorzunehmen und die Webanwendung zu aktivieren. Auf diese Weise können Sie sicher sein, dass die Datei erneut gelesen wird und für jeden Test eine "saubere" Umgebung vorhanden ist.

+0

Ich habe die Frage mit einigen Details aktualisiert. In diesem Kontext (Leistungstest) verwenden wir nicht IIS. Auf die Assemblies wird lokal verwiesen. Ich verwende Xml-Bibliotheken, um in die .config-Datei zu schreiben. Während der Ausführung kann ich sehen, dass die Datei geschrieben und geändert wird. –

1

Angenommen, dass die Dateizugriffsnummer auf die Konfigurationsdatei geschlossen wird, nachdem die Konfigurationsdatei gelesen und verarbeitet wurde, würde ich eine Nachricht an die Anwendung senden, damit sie die Konfigurationsdatei erneut liest, nachdem Sie die Datei aktualisiert haben. Wenn dieser Ansatz nicht funktioniert, vermute ich (wie Hogan vorgeschlagen hat), dass das Dateihandle nicht geschlossen ist. Welche Fehlercodes erhalten Sie beim Öffnen, Lesen und Schließen von Systemaufrufen? (Verwenden perror die Fehlermeldung zu melden)

+1

Dieser Ansatz ist interessant, aber können Sie mir einige Schritte zum Senden dieser Nachricht an die Anwendung geben? Ich habe versucht, ConfigurationManager.RefreshSection() aufzurufen, aber es hat nicht geklappt. –

+1

@born zu hula: Wie änderst du die Konfiguration @ Runtime? Ich würde den gleichen Ansatz verwenden, um die Anwendung die Konfigurationsdatei erneut lesen zu lassen. Welche Sprache und welches Betriebssystem verwenden Sie? Welche Nachrichten werden während des Tests an die Anwendung gesendet? Kommt die Eingabe für die Anwendung von einer Webseite? Die Beantwortung dieser Fragen würde einige Hinweise auf den besten Ansatz für Ihre Situation geben. –

+0

Ich verwende XmlDocument, um die .config-Datei zu ändern (siehe die aktualisierte Frage). Aber unabhängig davon, wie oft ich es ändere, werden die Änderungen nur einmal im Ausführungskontext reflektiert. Ich benutze C# und Windows XP. Die Eingabe aus der Anwendung kommt direkt aus dem Formular. Im Wesentlichen ist die Haupteingabe eine Nachricht, aus der eine Vielzahl von Objekten erstellt wird. –

24

Ich verstehe, dass dies ein ziemlich alter Thread ist, aber ich konnte die aufgelisteten Methoden nicht funktionieren. Hier ist eine einfachere Version der UpdateAppSettings Methode (unter Verwendung von .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"); 
     } 

Ziemlich lesbar und vermeidet, um die app.config durchquert mit XPath oder dergleichen. Hinweis: Der obige Code ist inspiriert von this Snippet auf MSDN.

Verwandte Themen