2016-10-01 1 views
1

Je reçois des exceptions lorsque j'essaie d'utiliser des sections app.config personnalisées dans mon service Windows. J'ai écrit avec succès des sections personnalisées dans d'autres applications, donc je suis sûr que j'ai les bons mécanismes et qu'il y a quelque chose qui se passe quand les services Windows sont impliqués. Je peux inclure le Xml app.config si nécessaire.Le service Windows C# ne peut pas utiliser GetSection() avec ConfigurationSection personnalisée

première tentative

J'ai le code suivant dans une fenêtre C# constructeur du service:

int systemErrorWindowSeconds = 
    ServiceSettings.Current.ExceptionHandling.SystemErrorWindowSeconds; 

Et ServiceSettings (les bits importants) est la suivante:

public class ServiceSettings : ConfigurationSection 
{ 
    private static ServiceSettings settings; 

    static ServiceSettings() 
    { 
     var config = 
      ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 

     settings = config.GetSection("serviceSettings") as ServiceSettings; 
    } 

    public static ServiceSettings Current { get { return settings; } } 

Lorsque Je tente d'accéder à ServiceSettings.Current Je reçois l'exception suivante:

Application: BTR.Evolution.Service.exe 
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: System.Configuration.ConfigurationErrorsException 
    at System.Configuration.BaseConfigurationRecord.EvaluateOne(System.String[], System.Configuration.SectionInput, Boolean, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object) 
    at System.Configuration.BaseConfigurationRecord.Evaluate(System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, Boolean, Boolean, System.Object ByRef, System.Object ByRef) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef) 
    at System.Configuration.Configuration.GetSection(System.String) 
    at BTR.Evolution.Service.ServiceSettings..cctor() Exception Info: System.TypeInitializationException 
    at BTR.Evolution.Service.ServiceSettings.get_Current() 
    at BTR.Evolution.Service.EvolutionService..ctor(System.String[]) 
    at BTR.Evolution.Service.Program.Main(System.String[]) 

Deuxième tentative:

je changé ma classe ServiceSettings utiliser GetSection comme:

static ServiceSettings() 
{ 
    settings = ConfigurationManager.GetSection("serviceSettings") as ServiceSettings; 
} 

Je reçois l'exception suivante (la plupart du temps comme ci-dessus, mais utilise ConfigurationManager et quelques appels plus GetSectionRecursive)

Application: BTR.Evolution.Service.exe 
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: 
    System.Configuration.ConfigurationErrorsException 
    at System.Configuration.BaseConfigurationRecord.EvaluateOne(System.String[], System.Configuration.SectionInput, Boolean, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object) 
    at System.Configuration.BaseConfigurationRecord.Evaluate(System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, Boolean, Boolean, System.Object ByRef, System.Object ByRef) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef) 
    at System.Configuration.BaseConfigurationRecord.GetSection(System.String) 
    at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(System.String) 
    at System.Configuration.ConfigurationManager.GetSection(System.String) 
    at BTR.Evolution.Service.ServiceSettings..cctor() Exception Info: System.TypeInitializationException 
    at BTR.Evolution.Service.ServiceSettings.get_Current() 
    at BTR.Evolution.Service.EvolutionService..ctor(System.String[]) 
    at BTR.Evolution.Service.Program.Main(System.String[]) 

Troisième tentative

j'ai changé mon constructeur de ServiceSettings essayer:

var customConfig = 
    ConfigurationManager.OpenExeConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 

settings = customConfig.GetSection("serviceSettings") as ServiceSettings; 

et moi avons eu l'exception suivante. Fondamentalement, la variable de paramètres a été affectée à null (pas d'exceptions 'gestionnaire de configuration') de sorte que l'appelant utilisant l'objet obtient une exception nulle.

Application: BTR.Evolution.Service.exe 
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: System.NullReferenceException 
    at BTR.Evolution.Service.EvolutionService..ctor(System.String[]) 
    at BTR.Evolution.Service.Program.Main(System.String[]) 

L'ultime tentative

j'ai changé mon constructeur de ServiceSettings pour essayer d'utiliser un resovler d'assemblage.

Func<object, ResolveEventArgs, System.Reflection.Assembly> getAssembly = 
    (sender, args) => typeof(ServiceSettings).Assembly; 

var resolveHandler = new System.ResolveEventHandler(getAssembly); 

AppDomain.CurrentDomain.AssemblyResolve += resolveHandler; 

var customConfig = 
    ConfigurationManager.OpenExeConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 

settings = customConfig.GetSection("serviceSettings") as ServiceSettings; 

AppDomain.CurrentDomain.AssemblyResolve -= resolveHandler; 

Mais j'ai obtenu exactement le même résultat que ma troisième tentative.

Un conseil pour commencer à travailler serait grandement apprécié. Faites-moi savoir si je dois fournir des informations supplémentaires.

+0

Process Monitor est susceptible d'être un outil de diagnostic utile, pour voir si.NET ouvre le fichier de configuration correct et si ce n'est pas juste ce qu'il fait mal. Vous pouvez le télécharger sur le site Web de Microsoft. –

+0

Catastrophe est arrivé ... mon PC s'est écrasé ... désolé pour le retard. Finalement, je suis revenu à ça. Le moniteur de processus montre qu'il frappe le bon fichier, mais il ne lit pas correctement les paramètres appliqués. Il a CREATE, READ, READ, CLOSE pour le fichier C: \ BTR \ Source \ Evolution.Service \ BTR.Evolution.Service \ bin \ Debug \ BTR.Evolution.Service.exe.config mais tous les changements de paramètres que je mets dedans ne sont pas lus. Est-ce que c'est ce que vous vouliez que je confirme? – Terry

+1

Je ne suis pas sûr de ce que je pensais, exactement, mais il est bon de savoir qu'il est certainement en train de lire le fichier que vous attendiez. Avez-vous essayé d'exécuter le même constructeur avec le même fichier de configuration mais en tant que programme normal plutôt que service? Cela peut être quelque chose d'aussi simple qu'une erreur de syntaxe dans le fichier de configuration. –

Répondre

0

Hmm, peu gêné. J'ai fait une nouvelle application de la console comme suggéré en utilisant le même code et les paramètres et cela a fonctionné. J'ai donc réexaminé mon service Windows et j'essayais d'utiliser un résolveur d'assemblage personnalisé pour localiser le fichier/la section de configuration. Je suppose que lorsque j'ai écrit le service à l'origine, j'avais des problèmes et j'ai essayé ce résolveur personnalisé (qui ne fonctionnait toujours pas). C'est quand j'ai posté cette question. Mais pour le coup, je remets juste la configuration standard ConfigurationManager.GetSection (deuxième méthode ci-dessus) pour obtenir la section personnalisée et cela a fonctionné. Ne peut pas l'expliquer