2016-05-06 5 views
1

Ich habe einen benutzerdefinierten Konfigurationsabschnitt, eine Sammlung und ein Element zum Hinzufügen/Ändern zu meiner app.config geschrieben. Alles scheint gut zu laufen und läuft perfekt in Visual Studio. Allerdings, wenn ich die Anwendung zu installieren und es kommt Zeit, um die neuen Daten an den benutzerdefinierten Konfigurationsabschnitt wird folgende Ausnahme speichern geworfen:Benutzerdefinierter Konfigurationsabschnitt kann nur während der Ausführung als Administrator gespeichert/geändert werden?

System.Configuration.ConfigurationErrorsException: Unable to save config to file '{path to config file}' 

Der interessante Teil ist, dass, wenn ich die Anwendung im Administrator-Modus laufen, alles funktioniert gut. Gibt es einen Grund, warum es nur als Administrator funktionieren würde?

EDIT:

Ich sollte anmerken, dass ich nicht glaube, es ist ein Problem, weil Zugriffsrechte a) wir andere Anwendungen haben, die die <applicationSettings> ihrer app.configs ganz gut da und b) log4net ist in der Lage ändern um seine Protokolldatei dort gut zu schreiben.

Benutzerdefinierte Config Element:

public class AuditorColorElement : ConfigurationElement 
{ 
    public AuditorColorElement() 
    { 
    } 

    public AuditorColorElement(Color color, string auditor) 
    { 
     Color = color; 
     Auditor = auditor; 
    } 

    [ConfigurationProperty(nameof(Color), IsRequired = true, IsKey = true)] 
    public Color Color 
    { 
     get { return (Color)base[nameof(Color)]; } 
     set { this[nameof(Color)] = value; } 
    } 

    [ConfigurationProperty(nameof(Auditor), IsRequired = true)] 
    public string Auditor 
    { 
     get { return (string)base[nameof(Auditor)]; } 
     set { this[nameof(Auditor)] = value; } 
    } 
} 

Benutzerdefinierte Config Abschnitt:

[ConfigurationCollection(typeof(AuditorColorElement))] 
public class AuditorColorElementCollection : ConfigurationElementCollection, IEnumerable<AuditorColorElement> 
{ 
    internal const string PropertyName = "AuditorColors"; 

    public AuditorColorElementCollection() : base() 
    { 
    } 

    public AuditorColorElementCollection(AuditorColorElementCollection collection) 
    { 
     foreach (AuditorColorElement element in collection) 
     { 
      Add(element); 
     } 
    } 

    public override ConfigurationElementCollectionType CollectionType 
    { 
     get 
     { 
      return ConfigurationElementCollectionType.AddRemoveClearMapAlternate; 
     } 
    } 

    protected override string ElementName 
    { 
     get 
     { 
      return PropertyName; 
     } 
    } 

    public AuditorColorElement this[int idx] 
    { 
     get { return (AuditorColorElement)BaseGet(idx); } 
    } 

    protected override bool IsElementName(string elementName) 
    { 
     return elementName.Equals(PropertyName, 
     StringComparison.InvariantCultureIgnoreCase); 
    } 

    public override bool IsReadOnly() 
    { 
     return false; 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new AuditorColorElement(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((AuditorColorElement)(element)).Color; 
    } 

    public void Add(AuditorColorElement element) 
    { 
     BaseAdd(element); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    public void Remove(AuditorColorElement element) 
    { 
     BaseRemove(element.Color); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(Color color) 
    { 
     BaseRemove(color); 
    } 

    public object GetKey(object key) 
    { 
     return BaseGet(key); 
    } 

    public bool ContainsKey(object key) 
    { 
     return GetKey(key) != null ? true : false; 
    } 

    public new IEnumerator<AuditorColorElement> GetEnumerator() 
    { 
     foreach (var key in this.BaseGetAllKeys()) 
     { 
      yield return (AuditorColorElement)BaseGet(key); 
     } 
    } 
} 

Benutzerdefinierte Config Abschnitt

public class AuditorColorSection : ConfigurationSection 
{ 
    [ConfigurationProperty(nameof(AuditorColors), IsRequired = true, IsDefaultCollection = true)] 
    [ConfigurationCollection(typeof(AuditorColorElementCollection), 
     AddItemName = "add", 
     ClearItemsName = "clear", 
     RemoveItemName = "remove")] 
    public AuditorColorElementCollection AuditorColors 
    { 
     get { return ((AuditorColorElementCollection)(base[nameof(AuditorColors)])); } 
     set { base[nameof(AuditorColors)] = value; } 
    } 

    public AuditorColorSection() 
    { 
     AuditorColors = new AuditorColorElementCollection(); 
    } 
} 
+0

Wo schreiben Sie? Wo physisch? Hat der Benutzer, der Ihre App ausführt, die Erlaubnis, dort zu schreiben? – mariocatch

+0

Ich denke, das könnte Ihnen helfen [Wie Admin-Rechte für die Bearbeitung von app.config in C# bekommen?] (Http://stackoverflow.com/questions/3147171/how-to-get-admin-privileges-for-editing-app -config-in-c) –

+0

@mariocatch zu Program Schreiben, aber auch andere Anwendungen in unserer Suite Konfigurationsdateien ändern ganz gut, dass auch dort gespeichert sind. Gibt es einen Unterschied zwischen dem Abschnitt , der geändert wird (der für unsere anderen Apps funktioniert) und einem benutzerdefinierten Abschnitt in Bezug auf Berechtigungen? Außerdem verwendet meine App log4net, das offenbar kein Problem hat, das Protokoll an diesen Ort zu schreiben. – Hershizer33

Antwort

2

Ich bin kein Fan der Verwendung von Methoden in der System.Configuration Namespace zu schreiben zu Config-Dateien. Das Lesen von Werten mit Methoden im System.Configuration-Namespace ist nie ein Problem.

Nur LinqToXML stattdessen verwenden, zumindest zu prüfen, ob das das Problem ist.

Ich vermute, Ihre App ist in C:\Program Data installiert, so während es Berechtigungen bezogen sein könnte Ich vermute, die Ursache der System.Configuration.ConfigurationErrorsException: Unable to save config to file ist ein lock on the file, use this code to check, wenn diese Annahme korrekt ist.

+0

So war ich nicht mit' System.Configuration' Namespace die eigentlichen Datei (Datei zu schreiben, wurde von Add- erstellt -> New Item in VS selbst und gesetzt, um auf Ausgabe zu kopieren), aber es war nur eine leere Konfigurationsdatei mit dem Standard-Tag von . Wie bereits erwähnt, trat der Fehler auf, wenn Sie versuchen, die Datei zu öffnen und Änderungen daran zu speichern. Was ich getan habe, um das Problem zu beheben, ist das Erstellen der XML-Datei im Code mit XML Writer und das Schreiben des '' - Tags der obersten Ebene. Der Rest des Codes war unverändert und dieses Mal funktioniert es.Bedeutet das Ihre Theorie, dass es abgeschlossen ist? – Hershizer33

+1

Alle von Ihnen verwendeten Attribute befinden sich im Namespace 'System.Configuration', z. B. [ConfigurationProperty] (https://msdn.microsoft.com/en-us/library/system.configuration.configurationproperty (v = vs.110) .aspx). Ich hatte Probleme mit dem Schreiben in Konfigurationsdateien mit diesen Methoden. Es war nur eine Ahnung/Vermutung/die Ursache für den Grund warum es fehlschlägt ist, weil die Datei gesperrt ist. Wenn es keine Berechtigungen gibt und keine Datei gefunden wird, ist die nächste logische Option, dass die Datei gesperrt ist. Der Hauptpunkt war stattdessen LinqToXML oder XML Writer. Ich bin froh, dass es funktioniert hat. –

+1

Danke mir auch, war sehr verwirrend und ich sehe immer noch nicht den Unterschied zwischen der Verwendung von 'System.Configuration' zum Bearbeiten einer Datei erstellte Kompilierzeit (hat nicht funktioniert) vs eine Datei zur Laufzeit erstellt (funktioniert über XMLWriter), aber vermute, es hat etwas mit Genehmigungen zu tun, aber darüber ist es nur Spekulationen. – Hershizer33

Verwandte Themen