Modifica App.config in fase di runtime

Sto scrivendo un’applicazione di test WinForms / C # / .NET 3.5 per il sistema che stiamo sviluppando e abbiamo avuto la necessità di passare da file .config al runtime, ma questo si sta rivelando un incubo.

Ecco la scena: l’applicazione WinForms ha lo scopo di testare una WebApp, divisa in 5 sottosistemi. Il processo di test funziona con i messaggi inviati tra i sottosistemi e affinché questo processo abbia esito positivo, ogni sottosistema deve avere il proprio file .config.

Per la mia applicazione di test ho scritto 5 file di configurazione separati. Mi piacerebbe essere in grado di passare tra questi 5 file durante il runtime, ma il problema è: posso modificare in modo programmatico il file .config dell’applicazione numerose volte, ma queste modifiche diventeranno effettive solo una volta. Ho cercato a lungo un modulo per risolvere questo problema, ma non ho ancora avuto successo.

So che la definizione del problema potrebbe essere un po ‘confusa, ma lo apprezzerei molto se qualcuno mi aiutasse.

Grazie in anticipo!

— AGGIORNAMENTO 01-06-10 —

C’è qualcosa che non ho menzionato prima. In origine, il nostro sistema è un’applicazione Web con chiamate WCF tra ogni sottosistema. Per motivi di test delle prestazioni (stiamo usando ANTS 4), abbiamo dovuto creare una copia locale degli assembly e farvi riferimento dal progetto di test. Potrebbe sembrare un po ‘sbagliato, ma non siamo riusciti a trovare un modo soddisfacente per misurare le prestazioni di un’applicazione remota.

— Fine aggiornamento —

Ecco cosa sto facendo:

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"); } 

AGGIORNARE

La soluzione seguente non ha funzionato perché XmlDocument non dispone e sembra che alcune versioni di .net non si chiudano correttamente quando viene fornito un percorso di file. La soluzione (codice di esempio nel collegamento) consiste nell’aprire un stream che eseguirà un dispose e lo passerà alla funzione di salvataggio.

Una soluzione è mostrata qui. http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


Roba vecchia di seguito

Prova questo:

Nota, ho cambiato in xpath, ma è passato un po ‘di tempo, quindi avrei potuto sbagliare xpath, ma in ogni caso dovresti usare xpath e non camminare sull’albero. Come puoi vedere è molto più chiaro.

Il punto importante è l’istruzione using che dispose() , che credo fosse il tuo problema.

Fammi sapere, buona fortuna.

  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"); } 

Capisco che questo è un thread piuttosto vecchio, ma non sono riuscito a far funzionare i metodi elencati. Ecco una versione più semplice del metodo UpdateAppSettings (utilizzando .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"); } 

Piuttosto leggibile ed evita di dover attraversare l’app.config usando Xpath o simili. Nota: il codice sopra è ispirato a questo snippet su MSDN.

La mia ipotesi è che non stai davvero chiudendo il file per la prima volta, in modo che Windows non “veda” le modifiche successive.

I miei suggerimenti sono di usare una chiamata API a IIS e distriggersre l’app Web (e il pool), apportare la modifica, accendere l’app Web. In questo modo sei sicuro che rileggerà il file e avrà un ambiente “pulito” per ogni test.

Supponendo che l’handle del file nel file di configurazione sia chiuso dopo che il file di configurazione è stato letto ed elaborato, invierei un messaggio all’applicazione per dirgli di rileggere il file di configurazione dopo aver aggiornato il file. Se questo approccio non funziona, allora sospetto (come suggerito da Hogan) che l’handle del file non sia chiuso. Quali codici di errore ricevi dal file che apre, legge e chiude le chiamate di sistema? (usa perror per segnalare il messaggio di errore)