Reputation: 27575
I develop a WPF application that uses NLog. It has been deployed to a few prospective customers, and in one of them, the application worked fine for a week and now it doesn't even open. That is, you double click the app icon, and nothing happens, literally. Not even the logging inside a AppDomain.CurrentDomain.UnhandledException
catch clause.
I was able to identify an event in the Windows Event Viewer (see message below).
What bogs me down is the sudden appearence of this error after a week of flawless operation, and my inability to interpret this message or finding info about it online.
Aplicativo: ForceViewer.exe
Versão do Framework: v4.0.30319
Descrição: O processo foi terminado devido a uma exceção sem tratamento.
Informações da Exceção: System.Xml.XmlException
em System.Xml.XmlTextReaderImpl.Throw(System.Exception)
em System.Xml.XmlTextReaderImpl.ParseDocumentContent()
em System.Xml.XmlTextReaderImpl.Read()
em System.Xml.XmlTextReader.Read()
em System.Configuration.XmlUtil..ctor(System.IO.Stream, System.String, Boolean, System.Configuration.ConfigurationSchemaErrors)
em System.Configuration.BaseConfigurationRecord.InitConfigFromFile()
Informações da Exceção: System.Configuration.ConfigurationErrorsException
em System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean)
em System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(System.Configuration.ConfigurationSchemaErrors)
em System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
em System.Configuration.ClientConfigurationSystem.OnConfigRemoved(System.Object, System.Configuration.Internal.InternalConfigEventArgs)
Informações da Exceção: System.Configuration.ConfigurationErrorsException
em System.Configuration.ConfigurationManager.PrepareConfigSystem()
em System.Configuration.ConfigurationManager.get_AppSettings()
em NLog.Common.InternalLogger.GetSettingString(System.String, System.String)
em NLog.Common.InternalLogger.GetSetting[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.String, System.String, Boolean)
em NLog.Common.InternalLogger.Reset()
em NLog.Common.InternalLogger..cctor()
Informações da Exceção: System.TypeInitializationException
em NLog.Common.InternalLogger.Log(System.Exception, NLog.LogLevel, System.String)
em NLog.Internal.ExceptionHelper.MustBeRethrown(System.Exception)
em NLog.LogFactory.get_Configuration()
em NLog.LogFactory.GetLogger(LoggerCacheKey)
em NLog.LogFactory.GetLogger(System.String)
em NLog.LogManager.GetLogger(System.String)
em Miotec.ForceViewer.App..cctor()
Informações da Exceção: System.TypeInitializationException
em Miotec.ForceViewer.App.Main(System.String[])
Here is my App.xaml.cs:
public partial class App : Application
{
static string AppName = "ForceViewer 1.1";
static readonly Mutex mutex = new Mutex(true, AppName);
// APPARENTLY the exception happens in the line below:
static readonly Logger logger = LogManager.GetLogger(typeof(App).FullName);
[STAThread]
public static void Main(string[] args)
{
SplashScreen splashScreen = new SplashScreen("Splash.png");
splashScreen.Show(true);
if (mutex.WaitOne(TimeSpan.Zero, true))
{
var app = new App();
app.InitializeComponent();
app.Run();
mutex.ReleaseMutex();
}
else
{
Extensions.EnviaMensagemPraAtivarOutraJanela();
}
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
WpfLauncher.Launch(this, new ForceViewerBootstrapper(AppName));
logger.Info($"Aplicação {AppName} iniciada");
}
}
UPDATE (with additional, possibly relevant info):
Some people mentioned NLog XML config file, but I am using a runtime configuration, as follows:
var dirname = Path.Combine(@"C:\\AppFolder", appName, "logs");
Directory.CreateDirectory(dirname);
var filename = Path.Combine(dirname, $"{appName}.log");
var filetarget = new FileTarget("app")
{
FileName = filename,
Encoding = Encoding.UTF8,
Layout = "${longdate}|${level:uppercase=true}|${message} (${logger:shortName=true})",
AutoFlush = true,
MaxArchiveFiles = 8,
ArchiveAboveSize = 1048576,
ArchiveEvery = FileArchivePeriod.Friday,
ConcurrentWrites = true
};
var asyncTarget = new AsyncTargetWrapper("app", filetarget);
var config = new LoggingConfiguration();
config.AddRuleForAllLevels(asyncTarget);
config.AddTarget(asyncTarget);
LogManager.Configuration = config;
Additionally, the "stack trace" (which in the case of a Windows Event seems to be printed sort of backwards) suggests NLog itself is getting an exception from the System.Configuration
classes, as seen from decompilation of InternalLogger
:
namespace NLog.Common { //... public static class InternalLogger { //... private static string GetSettingString(string configName, string envName) { // Line below seems to be throwing an exception string str = System.Configuration.ConfigurationManager.AppSettings[configName]; //..
Upvotes: 1
Views: 1358
Reputation: 36710
Probably there is a config mistake in your NLog (XML) config.
So why do you get a TypeInitializationException
and not a helpful message? That's because your initializing NLog before starting your program. The line:
static readonly Logger logger = LogManager.GetLogger(typeof(App).FullName);
will be run before the Main
because it's a static field. Unfortunately NLog cannot throw a better exception (see: Better TypeInitializationException (innerException is also null))
Recommendation: in this case is recommend to have a non-static Logger, or, a static Lazy<Logger>
:
static readonly Lazy<Logger> logger = new Lazy<Logger>(() => LogManager.GetLogger(typeof(App).FullName));
Upvotes: 3