简体   繁体   English

如何在Visual Studio中使用VSTO项目配置log4net

[英]How to configure log4net with VSTO project in visual studio

I was trying to build a simple outlook add in. I created a VSTO project in Visual Studio 2017 . 我试图构建一个简单的Outlook加载项。我在Visual Studio 2017中创建了一个VSTO项目。

When the project is created by the Visual Studio, there is no app.config or web.config in the solution. 通过Visual Studio创建项目时,解决方案中没有app.configweb.config I want to use log4net for this project. 我想为此项目使用log4net。 How should I configure it? 我应该如何配置? I tried to add web.config or app.config for the project. 我试图为该项目添加web.config或app.config。 But I was not able to get values from the configure file. 但是我无法从配置文件中获取值。 I think the project cannot recognize them. 我认为该项目无法识别它们。 I cannot use ConfigurationManager.AppSettings["key"] to get the value from the configure file. 我无法使用ConfigurationManager.AppSettings["key"]从配置文件中获取值。

Does anyone know how to use log4net in VSTO project? 有谁知道如何在VSTO项目中使用log4net?

Thank you. 谢谢。

Install Log4Net through the NuGet Package Manager. 通过NuGet软件包管理器安装Log4Net。 Then create a setting in the project properties, like asdf (you can delete the setting after you update the app.config file with the Log4Net sections), it will then create the app.config for you. 然后在项目属性中创建一个设置,例如asdf (您可以使用Log4Net部分更新app.config文件后删除该设置),然后它将为您创建app.config

屏幕截图

Here's the configuration in app.config for Log4Net I use on most of my projects. 这是我在大多数项目中使用的app.config的配置。 I created a new project with a setting asdf and added my standard Log4Net setup. 我使用设置asdf创建了一个新项目,并添加了我的标准Log4Net设置。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ExcelAddIn1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
      <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>
    <userSettings>
        <ExcelAddIn1.Properties.Settings>
            <setting name="asdf" serializeAs="String">
                <value>asdf</value>
            </setting>
        </ExcelAddIn1.Properties.Settings>
    </userSettings>
    <log4net>
        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline"/>
            </layout>
        </appender>
        <appender name="FileAppender" type="log4net.Appender.FileAppender">
            <file value="C:\Temp\MyOfficeAddIn.log"/>
            <appendToFile value="true"/>
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date|%-5level|%message%newline"/>
            </layout>
        </appender>
        <root>
            <level value="ALL"/>
            <appender-ref ref="FileAppender"/>
        </root>
    </log4net>
</configuration>

I usually create a class called ErrorHandler and add the following code. 我通常创建一个名为ErrorHandler的类并添加以下代码。

using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
using log4net;
using log4net.Config;

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

Then I use the following methods to write to the log file 然后我使用以下方法写入日志文件

    private static readonly ILog log = LogManager.GetLogger(typeof(ErrorHandler));

    /// <summary>
    /// Applies a new path for the log file by FileAppender name
    /// </summary>
    public static void SetLogPath()
    {
        XmlConfigurator.Configure();
        log4net.Repository.Hierarchy.Hierarchy h = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
        string logFileName = System.IO.Path.Combine(Properties.Settings.Default.App_PathLocalData, AssemblyInfo.Product + ".log");

        foreach (var a in h.Root.Appenders)
        {
            if (a is log4net.Appender.FileAppender)
            {
                if (a.Name.Equals("FileAppender"))
                {
                    log4net.Appender.FileAppender fa = (log4net.Appender.FileAppender)a;
                    fa.File = logFileName;
                    fa.ActivateOptions();
                }
            }
        }
    }

    /// <summary>
    /// Create a log record to track which methods are being used.
    /// </summary>
    public static void CreateLogRecord()
    {
        try
        {
            // gather context
            var sf = new System.Diagnostics.StackFrame(1);
            var caller = sf.GetMethod();
            var currentProcedure = caller.Name.Trim();

            // handle log record
            var logMessage = string.Concat(new Dictionary<string, string>
            {
                ["PROCEDURE"] = currentProcedure,
                ["USER NAME"] = Environment.UserName,
                ["MACHINE NAME"] = Environment.MachineName
            }.Select(x => $"[{x.Key}]=|{x.Value}|"));
            log.Info(logMessage);

        }
        catch (Exception ex)
        {
            ErrorHandler.DisplayMessage(ex);

        }
    }

    /// <summary> 
    /// Used to produce an error message and create a log record
    /// <example>
    /// <code lang="C#">
    /// ErrorHandler.DisplayMessage(ex);
    /// </code>
    /// </example> 
    /// </summary>
    /// <param name="ex">Represents errors that occur during application execution.</param>
    /// <param name="isSilent">Used to show a message to the user and log an error record or just log a record.</param>
    /// <remarks></remarks>
    public static void DisplayMessage(Exception ex, Boolean isSilent = false)
    {
        // gather context
        var sf = new System.Diagnostics.StackFrame(1);
        var caller = sf.GetMethod();
        var errorDescription = ex.ToString().Replace("\r\n", " "); // the carriage returns were messing up my log file
        var currentProcedure = caller.Name.Trim();
        var currentFileName = AssemblyInfo.GetCurrentFileName();

        // handle log record
        var logMessage = string.Concat(new Dictionary<string, string>
        {
            ["PROCEDURE"] = currentProcedure,
            ["USER NAME"] = Environment.UserName,
            ["MACHINE NAME"] = Environment.MachineName,
            ["FILE NAME"] = currentFileName,
            ["DESCRIPTION"] = errorDescription,
        }.Select(x => $"[{x.Key}]=|{x.Value}|"));
        log.Error(logMessage);

        // format message
        var userMessage = new StringBuilder()
            .AppendLine("Contact your system administrator. A record has been created in the log file.")
            .AppendLine("Procedure: " + currentProcedure)
            .AppendLine("Description: " + errorDescription)
            .ToString();

        // handle message
        if (isSilent == false)
        {
            MessageBox.Show(userMessage, "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

I have a project in GitHub you can use as an example . 我在GitHub上有一个项目可以作为示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM