【问题标题】:Writing to the ApplicationData folder with NLog Configuration API使用 NLog 配置 API 写入 ApplicationData 文件夹
【发布时间】:2018-08-08 15:41:28
【问题描述】:

我有一个与 WCF 服务捆绑在一起的桌面应用程序应用程序。两者都是使用 .NET 4.7.2 构建的。应用程序和服务共享一个安装目录,它们都使用 NLog 4.5.8 进行日志记录。它们各自使用 NLog 的方式的唯一区别是应用程序使用 NLog.config 文件来设置其日志记录属性,而服务使用 NLog Configuration API

请注意,我为该服务使用 NLog 配置 API 的原因是该服务似乎拒绝使用应用程序使用的 NLog.config 文件,即使它与它们两个位于同一目录中。除非我使用 NLog 配置 API 配置它,否则它根本不会记录。

无论如何,NLog 配置 API 似乎一切正常;但是,我无法像使用 NLog.config 文件一样将其定位到 ApplicationData 文件夹以存储日志文件。

在 NLog.config 文件中,ApplicationData 文件夹可以定位如下:

<target xsi:type="File"
        name="infoLogFile"
        layout="${longdate}|${level:uppercase=true}|${callsite}|${logger:shortName=true}: ${message}"
        fileName="${specialfolder:ApplicationData}\Program\file.log"
        keepFileOpen="false"
        archiveFileName="${specialfolder:ApplicationData}\Program\file_${shortdate}.{##}.log"
        archiveNumbering="Sequence"
        archiveEvery="Day"
        maxArchiveFiles="30"
/>

我使用 NLog 配置 API 设置了我的 FileTarget,如下所示:

var infoFileTarget = new FileTarget("infoFileTarget")
{
    Layout = @"${longdate}|${level:uppercase=true}|${callsite}|${logger:shortName=true}: ${message}",
    FileName = "${specialfolder:ApplicationData}/Program/file.log",
    KeepFileOpen = false,
    ArchiveFileName = "${specialfolder:ApplicationData}/Program/file_${shortdate}.{##}.log",
    ArchiveNumbering = ArchiveNumberingMode.Sequence,
    ArchiveEvery = FileArchivePeriod.Day,
    MaxArchiveFiles = 30,
};
config.AddTarget(infoFileTarget);

很遗憾,这不起作用。

但是,将 FileName/ArchiveFileName 设置为以下两项确实有效:

FileName = "${basedir}/Program/file.log", // this works

FileName = "C:/Users/<USERNAME>/AppData/Roaming/Program/file.log, // this works

似乎以 ApplicationData 文件夹为目标应该可行,但我一定遗漏了一些东西。有使用 NLog 经验的人知道我怎样才能让它工作吗?

提前感谢您的帮助!

【问题讨论】:

    标签: c# nlog


    【解决方案1】:

    如果您认为${specialfolder:ApplicationData}(或其他布局)不起作用,您可以将其记录到文件中。例如

    <target xsi:type="File"
            name="infoLogFile"
            layout="${longdate}|my application data folder: ${specialfolder:ApplicationData}"
            fileName="c:\temp\test.log"
    
    />
    

    我认为C:/Users/&lt;USERNAME&gt;/AppData/Roaming/Program/file.log 中的用户名可能出乎意料。

    旁注:

    ${specialfolder} 在完整的 .NET 框架和 .NET Standard 2 中受支持,而不是 .NET 标准 1。NLog 使用 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) 来检索文件夹。

    【讨论】:

    • 谢谢,朱利安。您的回答使我发现 ApplicationData 文件夹在 LocalSystem 帐户下运行的 Windows 服务引用时引用了不同的位置。将我的日志记录位置切换到 CommonApplicationData,它的位置在 LocalSystem 帐户下运行的 Windows 服务引用时不会改变,对我来说是一个可行的解决方法。
    【解决方案2】:

    我进行了更多挖掘,结果发现我的问题实际上正在发生,因为Environment.SpecialFolder.ApplicationData 在 LocalSystem 帐户下运行的 Windows 服务引用时引用了不同的位置,而不是由于 NLog 中的错误。我的解决方法是选择登录到 Environment.SpecialFolder.CommonApplicationData 文件夹,因为当 Windows 服务引用该位置时,该位置不会改变。

    我使用this reference 提出了我的解决方案。

    【讨论】:

    • 我发现我也必须使用 CommonApplicationData,这是一个 Windows 应用程序(不是服务)
    【解决方案3】:

    This nlog bug 建议 specialfolder 不适用于 dot net core。

    解决方法似乎是:

    <variable name="logFolder"
     value="${environment:variable=APPDATA:whenEmpty=${environment:variable=HOME}}/Log" />
    

    【讨论】:

    • 不幸的是,这在 .NET 4.7.2 中似乎不起作用
    • ${specialFolder} 在 .NET Standard 1 中不受支持,但在完整框架和 .NET Standard 2 中提供。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多