Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplest way to support logging from a VSTO AddIn

Tags:

c#

logging

vsto

I have written a simple MS Word AddIn in Visual Studio 2013, and I would like to be able to log events, preferbly to the Windows Event Viewer. It seems that I will run into permission issues if I try to create a new event source for my application. I am looking for the simplest approach to enable logging events from my VSTO that does not violate good programming guidelines.

Option 1: Use the VSTO 4.0 source

I see from the MSDN documentation on Event Logging for Office Solutions that:

You can use the event viewer in Windows to see exception messages that are captured by the Visual Studio Tools for Office runtime when you install or uninstall Office solutions. You can use these messages from the event logger to resolve installation and deployment problems.

These events are logged using the VSTO 4.0 source. Can I use the VSTO 4.0 source to log errors from my own AddIn, or would this considered bad practice?

Edit: From Eugene Astafiev's answer and what I've read elsewhere it seems this would be a bad approach since the VSTO 4.0 source is only supposed to deal with the management of the AddIns, not the AddIns themselves. Answers to other questions have also advised against using "generic" sources.

Option 2: Create a bootstrap app to be included in the installer

As an alternative, I could include a simple bootstrap application which creates the source during installation, but I can't see how to add my own prerequisites using the Install Settings under Properties > Publish in Visual Studio. Can it be done? Is there another way to do it? I would prefer not to have to create an InstallShield Windows Installer since in every other respect the installer created by default works well for my purposes. It seems like overkill to create a full installer just to get event logging working.

Edit: So far, it seems that there is no "easy" way to do this, although it is not too complicated to create an installer by following the linked instructions.

Option 3: Use a logging framework and log to a file

A third option would be to use log4net or similar logging framework and configure a File Appender to log to a file.

Initially I was not very keen to implement file logging, because a) My application would not be logging very frequently, and b) I wanted to avoid having log files scattered in various locations that are hard to find.

Edit: This is the option I have taken so far, since it required the least configuration and is adaptable if my logging requirements change in the future.

like image 315
rudivonstaden Avatar asked Feb 16 '15 12:02

rudivonstaden


2 Answers

It is relatively straightforward to setup log4net to handle simple (or complex) logging requirements. The log4net Tutorial on CodeProject provides a useful reference.

  1. Install log4net to your project using the NuGet Package Manager or Package Manager Console if you prefer.
  2. Add an App.config file if you don't have one already (right-click your project, select Add > New Item... and select Application Configuration File from Visual C# Items).
  3. Edit the App.config file to look something like this (replacing MyAddIn appropriately in the <file /> tag):

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
      </configSections>
      <log4net>
        <root>
          <level value="ALL"/> 
          <appender-ref ref="RollingFileAppender"/>
        </root>
        <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="${APPDATA}\My AddIn\MyAddin-log.txt" />
          <appendToFile value="true" />
          <rollingStyle value="Size" />
          <maxSizeRollBackups value="5" />
          <maximumFileSize value="5MB" />
          <staticLogFileName value="true" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
          </layout>
        </appender>
      </log4net>
    </configuration>
    

    Log files will be saved to the user's roaming AppData (%appdata%) folder, keeping up to 5 rolling log files which do not exceed 5MB each.

  4. Add the following line to ThisAddIn_Startup() in ThisAddIn.cs (you will need to add a using log4net; directive):

    log4net.Config.XmlConfigurator.Configure();
    
  5. Add the following statement to any class which needs to implement logging:

    private static readonly log4net.ILog log = 
        log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    
  6. Events can then be logged using the log.Info, log.Warn, log.Error, log.Fatal and other methods provided by log4net.

You may get schema warning messages because log4net does not include a schema, and Visual Studio cannot then validate the config section. In that case, download the schema file from http://csharptest.net/downloads/schema/log4net.xsd to somewhere accessible. The location C:\Program Files\Microsoft Visual Studio 10.0\Xml\Schemas has been suggested elsewhere.

Select your App.config file in Visual Studio, and click into the editor. You should get an XML menu item. From there, select Schemas... and add the log4net.xsd file from where you saved it.

Note that you can also use log4net to log to the Event Viewer but you will run into the same permission issues raised in the initial question.

like image 77
rudivonstaden Avatar answered Oct 31 '22 17:10

rudivonstaden


You need to differentiate VSTO exceptions that can be captured when installing or uninstalling the software and add-in specific events handled in your code. The Event Logging for Office Solutions article explains how to capture the Visual Studio Tools for Office runtime exceptions when you install or uninstall Office solutions.

If you need to log the add-in events you can use any .Net based components and BCL. For example, see What is the best way to write event log entries?.

like image 31
Eugene Astafiev Avatar answered Oct 31 '22 18:10

Eugene Astafiev