2016-10-03 2 views
1

J'essaie de déboguer ce que je crois être un problème de liaison WPF qui se produit uniquement sur une machine en production - Je ne peux pas repro sur une machine développeur . Pour ce faire, j'ai essayé d'obtenir les informations de trace de liaison à produire dans un fichier journal. Les réponses suivantes like this one, je suis en mesure d'obtenir à la sortie vers un emplacement codé en dur en configurant dans App.config:Impossible d'obtenir des informations de trace d'erreur de liaison WPF pour écrire dans le fichier journal configuré dans le code

<system.diagnostics> 
    <sources> 
    <source name="System.Windows.Data" switchName="SourceSwitch" > 
     <listeners> 
     <add name="textListener" /> 
     </listeners> 
    </source> 
    </sources> 

    <switches> 
    <add name="SourceSwitch" value="All" /> 
    </switches> 

    <sharedListeners> 
    <add name="textListener" 
    type="System.Diagnostics.TextWriterTraceListener" 
    initializeData="c:\BindingErrors.log" /> 
    </sharedListeners> 

    <trace autoflush="true" indentsize="4"/> 
</system.diagnostics> 

Cela fonctionne bien sur ma machine où j'ai des droits d'administrateur au c:\ lecteur . Le problème est que je veux écrire le journal quelque part où l'utilisateur a des droits, par ex. leur dossier TEMP. Donc, je veux faire quelque chose comme ça, en utilisant la variable d'environnement %TEMP%:

initializeData="%TEMP%\BindingErrors.log" 

Ce ne fonctionne pas, cependant, et je suppose que cela ne fonctionnera pas - see this answer; Donc, en suivant les conseils de cette réponse, j'ai essayé de configurer la sortie via le code au lieu de App.config. Voici ce que j'ai essayé jusqu'à présent:

var listener = new 
    TextWriterTraceListener(Environment.ExpandEnvironmentVariables(
    @"%TEMP%\BindingErrors.log"), "myListener"); 

Trace.Listeners.Add(listener); 
Trace.WriteLine("foo"); // just to see if it works at all. 
Trace.Flush(); 

Mais ce n'écrit que foo dans le fichier journal dans le dossier %TEMP%. Il n'écrit pas les erreurs de liaison. J'ai essayé de reproduire ce que le App.config avait, mais il n'y a pas de collecte Sources, alors quand j'instancier un TraceSource, comme ceci:

var source = new TraceSource("mySource", SourceLevels.Information); 

Je ne sais pas quoi faire avec elle, et il n'y a pas Listeners collection à laquelle je peux ajouter mon instance listener. MSDN ne semble pas tout rassembler pour moi, ou il me manque quelques détails critiques. Quelqu'un peut-il m'aider s'il vous plaît à comprendre ce que je fais mal?

Répondre

1

& hellip, il n'y a pas de collection Listeners à laquelle je peux ajouter mon instance d'écouteur.

En fait, il y a: PresentationTraceSources.DataBindingSource.Listeners

La propriété renvoie l'objet TraceSource qui est utilisé lorsque des données sont des messages de liaison de sortie. Vous pouvez ajouter n'importe quel écouteur à cette source, tel qu'un TextWriterTraceListener que vous avez créé dans code-behind en développant la variable d'environnement %TEMP% et en l'utilisant comme répertoire pour votre fichier de sortie.

Notez que l'approche par programme nécessite une recompilation pour modifier l'emplacement de sortie ou l'ajout de toute autre valeur de configuration pouvant être lue au moment de l'exécution. Une technique différente vous permet de spécifier la configuration entière dans le fichier app.config, en implémentant un TraceListener personnalisé qui sait comment développer les variables d'environnement.

Par exemple:

namespace TestSO39836570TraceListenerBindingErrors 
{ 
    class EnvironmentAwareTextWriterTraceListener : TextWriterTraceListener 
    { 
     public EnvironmentAwareTextWriterTraceListener(string path) 
      : base(Environment.ExpandEnvironmentVariables(path)) 
     { } 

     public EnvironmentAwareTextWriterTraceListener(string path, string name) 
      : base(Environment.ExpandEnvironmentVariables(path), name) 
     { } 
    } 
} 

Puis dans l'application.fichier de configuration, vous pouvez spécifier l'auditeur:

<system.diagnostics> 
    <sources> 
    <source name="System.Windows.Data" switchName="SourceSwitch"> 
     <listeners> 
     <add name="textListener"/> 
     </listeners> 
    </source> 
    </sources> 

    <switches> 
    <add name="SourceSwitch" value="All"/> 
    </switches> 

    <sharedListeners> 
    <add name="textListener" 
     type="TestSO39836570TraceListenerBindingErrors.EnvironmentAwareTextWriterTraceListener, TestSO39836570TraceListenerBindingErrors" 
     initializeData="%temp%\BindingErrors.log"/> 
    </sharedListeners> 

    <trace autoflush="true" indentsize="4"/> 
</system.diagnostics> 

Notez que lorsque vous spécifiez un type personnalisé TraceListener qui se trouve dans votre propre ensemble de programme, vous devez spécifier le nom de l'assemblage dans l'attribut type, en suivant l'intégration globale nom de type qualifié avec une virgule, puis le nom de l'assembly (dans l'exemple ci-dessus, l'espace de nom du type est identique au nom de l'assembly, par défaut pour un projet créé dans Visual Studio).

Vous pouvez bien sûr opter pour des noms d'espaces de noms et de types plus courts que ceux que j'ai utilisés ici. :)

+0

Merci Peter! –