从 Outlook 加载项调用时,NLog 不写入日志文件
NLog does not write to log file when called from Outlook Add-in
我有一个用于 Outlook 的 C# 加载项 (Add-In Express),我试图从中存储一些日志数据,但即使对记录器的调用没有失败,也没有创建日志文件。我在 Win 10 环境中使用 VS 2013。
我的NLog.Config文件(保存在文件夹OutlookAddin\bin\Debug,与OutlookAddIn.dll.config相同的位置)如下:
<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File"
layout="${longdate} ${logger} ${message}"
fileName="${specialfolder:ApplicationData}\FindAlike\NewMails.txt"
keepFileOpen="false"
encoding="iso-8859-2" />
</targets>
<rules>
<logger name="*" writeTo="file" />
</rules>
加载项中的代码是声明:
public AddinModule()
{
Application.EnableVisualStyles();
InitializeComponent();
// Please add any initialization code to the AddinInitialize event handler
}
private ADXOutlookAppEvents adxOutlookEvents;
private DateTime LastReceivedDate = DateTime.Now;
private Timer mailCheckTimer;
public static RegistryKey SoftwareKey = Registry.CurrentUser.OpenSubKey("Software", true);
public static RegistryKey AppNameKey = SoftwareKey.CreateSubKey("FindAlike");
public static Logger logger = LogManager.GetCurrentClassLogger();
测试日志文件写入的例程是:
public static void TestNLog()
{
try
{
NLog.LogManager.ThrowExceptions = true;
logger.Info("test1");
logger.Warn("test2");
logger.Error("test3");
var fileTarget1 = (FileTarget)NLog.LogManager.Configuration.FindTargetByName("file");
var logEventInfo = new LogEventInfo { TimeStamp = DateTime.Now };
string fileName = fileTarget1.FileName.Render(logEventInfo);
if (!System.IO.File.Exists(fileName))
throw new Exception("Log file does not exist.");
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
调用TestNLog时,虽然目标文件正确,但出现日志文件不存在的Message,说明配置文件读取成功
当包含在可执行文件中时,相同的代码按预期工作。
另一个 Whosebug 问题 (How to use NLog for a DLL) 建议 NLog.config 需要放在与调用插件的可执行文件相同的目录中。这解决了问题。然而,这使得分发非常困难,因为 Outlook 可执行文件的位置会根据 Outlook 版本而有所不同,并且需要管理员权限才能将文件复制到其中。也许另一个记录器不需要这个。
感谢@Julian 的建议,以下代码以编程方式指定了 NLog 配置,并且 运行 从外接程序成功:
using NLog;
using NLog.Config;
using NLog.Targets;
using System.Xml;
...
public static Logger logger = LogManager.GetCurrentClassLogger();
....
public static void ConfigNLog()
{
string xml = @"
<nlog xmlns=""http://www.nlog-project.org/schemas/NLog.xsd""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
<targets>
<target name=""file"" xsi:type=""File""
layout=""${longdate} ${logger} ${message}""
fileName=""${specialfolder:ApplicationData}\FindAlike\NewMails.txt""
keepFileOpen=""false""
encoding=""iso-8859-2"" />
</targets>
<rules>
<logger name=""*"" writeTo=""file"" />
</rules>
</nlog>";
StringReader sr = new StringReader(xml);
XmlReader xr = XmlReader.Create(sr);
XmlLoggingConfiguration config = new XmlLoggingConfiguration(xr, null);
NLog.LogManager.Configuration = config;
}
除了@SimonKarvis 的回答,nlog.config 的位置可能很困难。这与单元测试相同。
我会推荐:
从 C# 创建配置,例如
var target = new FileTarget
{
FileName = logfile,
ReplaceFileContentsOnEachWrite = true,
CreateDirs = createDirs
};
var config = new LoggingConfiguration();
config.AddTarget("logfile", target);
config.AddRuleForAllLevels(target);
LogManager.Configuration = config;
或从字符串加载配置:
string configXml = "<nlog>...<nlog>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(configXml);
var config = new XmlLoggingConfiguration(doc.DocumentElement, Environment.CurrentDirectory);
LogManager.Configuration = config;
或者至少但不是最后,找到 nlog.config 和 "feed" 到 NLog 的正确路径。
var pathToNlogConfig = "c:\..";
var config = new XmlLoggingConfiguration(pathToNlogConfig);
LogManager.Configuration = config;
我有一个用于 Outlook 的 C# 加载项 (Add-In Express),我试图从中存储一些日志数据,但即使对记录器的调用没有失败,也没有创建日志文件。我在 Win 10 环境中使用 VS 2013。
我的NLog.Config文件(保存在文件夹OutlookAddin\bin\Debug,与OutlookAddIn.dll.config相同的位置)如下:
<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File"
layout="${longdate} ${logger} ${message}"
fileName="${specialfolder:ApplicationData}\FindAlike\NewMails.txt"
keepFileOpen="false"
encoding="iso-8859-2" />
</targets>
<rules>
<logger name="*" writeTo="file" />
</rules>
加载项中的代码是声明:
public AddinModule()
{
Application.EnableVisualStyles();
InitializeComponent();
// Please add any initialization code to the AddinInitialize event handler
}
private ADXOutlookAppEvents adxOutlookEvents;
private DateTime LastReceivedDate = DateTime.Now;
private Timer mailCheckTimer;
public static RegistryKey SoftwareKey = Registry.CurrentUser.OpenSubKey("Software", true);
public static RegistryKey AppNameKey = SoftwareKey.CreateSubKey("FindAlike");
public static Logger logger = LogManager.GetCurrentClassLogger();
测试日志文件写入的例程是:
public static void TestNLog()
{
try
{
NLog.LogManager.ThrowExceptions = true;
logger.Info("test1");
logger.Warn("test2");
logger.Error("test3");
var fileTarget1 = (FileTarget)NLog.LogManager.Configuration.FindTargetByName("file");
var logEventInfo = new LogEventInfo { TimeStamp = DateTime.Now };
string fileName = fileTarget1.FileName.Render(logEventInfo);
if (!System.IO.File.Exists(fileName))
throw new Exception("Log file does not exist.");
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
调用TestNLog时,虽然目标文件正确,但出现日志文件不存在的Message,说明配置文件读取成功
当包含在可执行文件中时,相同的代码按预期工作。
另一个 Whosebug 问题 (How to use NLog for a DLL) 建议 NLog.config 需要放在与调用插件的可执行文件相同的目录中。这解决了问题。然而,这使得分发非常困难,因为 Outlook 可执行文件的位置会根据 Outlook 版本而有所不同,并且需要管理员权限才能将文件复制到其中。也许另一个记录器不需要这个。
感谢@Julian 的建议,以下代码以编程方式指定了 NLog 配置,并且 运行 从外接程序成功:
using NLog;
using NLog.Config;
using NLog.Targets;
using System.Xml;
...
public static Logger logger = LogManager.GetCurrentClassLogger();
....
public static void ConfigNLog()
{
string xml = @"
<nlog xmlns=""http://www.nlog-project.org/schemas/NLog.xsd""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
<targets>
<target name=""file"" xsi:type=""File""
layout=""${longdate} ${logger} ${message}""
fileName=""${specialfolder:ApplicationData}\FindAlike\NewMails.txt""
keepFileOpen=""false""
encoding=""iso-8859-2"" />
</targets>
<rules>
<logger name=""*"" writeTo=""file"" />
</rules>
</nlog>";
StringReader sr = new StringReader(xml);
XmlReader xr = XmlReader.Create(sr);
XmlLoggingConfiguration config = new XmlLoggingConfiguration(xr, null);
NLog.LogManager.Configuration = config;
}
除了@SimonKarvis 的回答,nlog.config 的位置可能很困难。这与单元测试相同。
我会推荐:
从 C# 创建配置,例如
var target = new FileTarget { FileName = logfile, ReplaceFileContentsOnEachWrite = true, CreateDirs = createDirs }; var config = new LoggingConfiguration(); config.AddTarget("logfile", target); config.AddRuleForAllLevels(target); LogManager.Configuration = config;
或从字符串加载配置:
string configXml = "<nlog>...<nlog>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(configXml); var config = new XmlLoggingConfiguration(doc.DocumentElement, Environment.CurrentDirectory); LogManager.Configuration = config;
或者至少但不是最后,找到 nlog.config 和 "feed" 到 NLog 的正确路径。
var pathToNlogConfig = "c:\.."; var config = new XmlLoggingConfiguration(pathToNlogConfig); LogManager.Configuration = config;