Microsoft OneNote Programing & Automation using C#

As I start this, I don’t know how it will end up. Maybe in failure, hopefully success.

Without knowing exactly how, my goal is to learn how to interact with Microsoft OneNote via code and hopefully extract data in some meaningful way. If I can get that far, I think I have a few prototype ideas that can use this code.

I’ve done a little bit of Excel Macro programming but where do we start with OneNote programming?

First, I’m pretty sure we’ll be using some sort of Visual Basic for Applications (VBA) or C# solution created for OneNote.

References:

My OneNote Hello World App

The first reference link above has some sample code I’ll also show you below but this is my starting point, my “hello world” application for OneNote, if you will.

Right off the bat, in Visual Studio 2017, I get my first error when trying to compile the sample code. Of course every new thing we learning in coding is hard at first and this project is no exception.

The first issue is a code issue. If you’re trying this yourself, start a new .Net console application and try to run the original example code. If you get errors, try my corrected code example below first example code.

1st error was Visual Studio recommending code change from

using System;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Office.Interop.OneNote;

class Program
{
  static void Main(string[] args)
  {
    var onenoteApp = new Application();

    string notebookXml;
    onenoteApp.GetHierarchy(null, HierarchyScope.hsNotebooks, out notebookXml);
    
    var doc = XDocument.Parse(notebookXml);
    var ns = doc.Root.Name.Namespace;
    foreach (var notebookNode in 
      from node in doc.Descendants(ns + "Notebook") select node)
    {
      Console.WriteLine(notebookNode.Attribute("name").Value);
    }
  }
}

To this my update code that compiled

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.OneNote;

namespace OneNote_ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var onenoteApp = new Application();
            onenoteApp.GetHierarchy(null, HierarchyScope.hsNotebooks, out string notebookXml);

            var doc = XDocument.Parse(notebookXml);
            var ns = doc.Root.Name.Namespace;
            foreach (var notebookNode in
                from node in doc.Descendants(ns + "Notebook") select node)
            {
                Console.WriteLine(notebookNode.Attribute("name").Value);
            }       
        }
    }
}             

The 2nd was error CS1756: Interop type ‘IApplication’ cannot be embedded because it is missing the required ‘System.Runtime.InteropServices.ComImportAttribute’ attribute

This is a configuration issue, not code. Only took me about an hour of googling until I found this helpful article that seemed to solve this particular issue.

The article above shows you how to deal with this error by changing the assembly property for “Embed Interop Types” from True to False in the Assembly’s properties settings.

For Visual Studio 2017 on my simple console application it looks like this.

Included Microsoft.Office.Interop.OneNote PIA
Right click and select properties
Change Embed Interop Types from False to True to fix error CS1756: Interop type ‘IApplication’ cannot be embedded because it is missing the required ‘System.Runtime.InteropServices.ComImportAttribute’ attribute

What are Primary Interop Assemblies?

Primary Interop Assemblies or PIAs are used for Visual Studio projects that need to interact Microsoft Office products.

To use the features of a Microsoft Office application from an Office project, you must use the primary interop assembly (PIA) for the application. The PIA enables managed code to interact with a Microsoft Office application’s COM-based object model.

PIAs for Visual Studio is like including libraries in Visual Basic for Applications if you’ve ever written Excel macros, you might have had to include a library reference to get some code to work.

Its basically the same thing in C# with PIAs. We need some code to help us interact with Microsoft Office products and PIAs are how we do it.

References: