本文章是由機器翻譯。

OneNote 2010

使用 OneNote 物件模型建立 OneNote 2010 擴充

Andy Gray

下載程式碼範例

Microsoft Office OneNote 是功能強大的數位筆記本的收集]、 [組織]、 [搜尋] 及 [共用資訊。Microsoft Office 2010 最近的版本,不只 OneNote 使用者經驗改善,但 OneNote 筆記本是現在更 「 內文 」 普遍使用。使用者可以同步處理電腦透過 Windows Live 之間的內容 ; 搜尋、 編輯與共用筆記從任何網頁瀏覽器中 ; 以及完整的筆記本從 Windows Mobile (和存取,很快就,Windows 電話 7)。進一步,OneNote 之前包含只在某些 Office] 版本中,但它現在 ’s Office 2010 的每個版本中。所有這些因素整合資訊管理解決方案的 OneNote 建立比以往更吸引人的機會。

這個本文中,我提供開發與資料從 Microsoft OneNote 2010 和 2007年互通的應用程式的概觀。在的程序中我介紹 OneNote 物件模型專案是免費提供 CodePlex 上,並示範這個程式庫如何讓容易將從 OneNote 筆記本、 區段和頁面的資訊整合到用戶端應用程式。

OneNote 開發的發展

最初發行的版本的 OneNote 2003 didn’t 提供外部應用程式的 API。不久就此後但是,OneNote 2003 預存程序 1年新增稱為 [OneNote 1.1 類型櫃,啟用的影像、 筆跡和 HTML 的程式設計匯入到 OneNote,透過簡單的類別稱為 CSimpleImporter 其中一個 COM 程式庫。值得注意的是,不過,只有這個類別所提供的資料匯入功能 ; 您可以用它來發送資料到 OneNote 筆記本,但不能取回內容以程式設計的方式。

發行的 OneNote 2007 帶來更強大的開發能力,使用新的 COM API,可讓您匯入、 匯出及以程式設計的方式修改 OneNote 2007 內容。OneNote 應用程式類別,該程式庫中的提供豐富的方法使用的集合:

  • 筆記本結構: 探索、 開啟、 修改、 關閉和刪除筆記本、 區段群組及區段
  • 網頁內容: 探索、 開啟、 修改、 儲存及刪除網頁內容
  • 瀏覽: 尋找]、 [連結至] 和 [瀏覽網頁及物件

大部份的這些方法傳回,或接受代表筆記本結構和內容頁面的 XML 文件。Saul Candib 撰寫兩個部分一連串,「 什麼 ’s 新的開發人員在 OneNote 2007,」 的文件在 msdn.microsoft.com/library/ms788684(v=office.12) ,這個 API,並在 msdn.microsoft.com/library/aa286798(office.12) 詳細的 XML 結構描述。

XML 結構描述的 OneNote 2010 是的 OneNote 2007 中相當類似。OneNote 2010 介紹以支援一些新功能 (例如連結的筆記、 版本控制、 網路共用、 多層子頁面和方程式支援) 的檔案格式變更。但是,OneNote 2010 可以繼續使用 OneNote 2007 筆記本上,而不變更檔案格式。在 OneNote 2010,從 OneNote 2007 檔案格式儲存的區段中擷取資料,將會產生類似於在 OneNote 2007 中的 XML 文件。在 XML 結構描述中的 OneNote 2010 區段的主要差異是附加的變更,以支援稍早列出的新功能。新的 XMLSchema 列舉型別是可用來表示 OneNote 的結構描述版本 ; 許多 OneNote 方法接受 XMLSchema 參數,以指出所要的結構描述版本的新多載。

已從 OneNote 2010,移除 CSimpleImporter] 類別引入 OneNote 2003 中,仍然可以使用 OneNote 2007 中的附註,因此使用這個類別的應用程式需要使用新的介面來使用 OneNote 2010 重寫。

存取使用 COM API 的 OneNote 資料

它 ’s 相當簡單,開始使用 OneNote COM API 來存取從 OneNote 筆記本的即時資料。開始在 Visual Studio 中建立新的主控台應用程式,然後再新增 [Microsoft OneNote 14.0 型別程式庫的 COM 元件 (如 OneNote 2010) 或 (OneNote 2007) Microsoft OneNote 12.0 型別程式庫的 COM 元件的參考。

如果您開發 OneNote 2010 應用程式使用 Visual Studio 2010,採取一些次要的相容性問題的附的註。先,以不相符的 OneNote Interop 組件,隨附 Visual Studio 2010,因為應該不會直接參考 [加入參考] 對話方塊中的 [.NET] 索引標籤上的 the
Microsoft.Office.Interop.OneNote 元件,但改參考 [COM] 索引標籤上的 [Microsoft OneNote 14.0 型別程式庫] 元件。這仍然會導致額外的專案 ’s 參考到 OneNote Interop 組件。

第二個,OneNote 14.0 型別程式庫不是與 Visual Studio 2010 「 NOPIA 」 功能 (主要 Interop 組件中未內嵌於應用程式預設) 相容。因此,請確定將內嵌 Interop 類型] 屬性設定為 OneNote Interop 組件參考。(這兩個這些問題被描述更詳細地 blogs.msdn.com/descapa/archive/2010/04/27/onenote-2010-and-visual-studio-2010-compatibility-issues.aspx 在 OneNote 專案經理奧 Escapa ’s 部落格上)。使用就地 OneNote 程式庫參考,您 ’re 可以讓 OneNote API 的呼叫。的 圖 1 中的程式碼來擷取 XML 文件包含一份 OneNote 筆記本,使用 GetHierarchy 方法,然後使用 LINQ to XML 來擷取和列印到主控台的 [筆記本] 名稱。

圖 1 的 列舉的筆記本

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);
    }
  }
}

當做第二個參數傳遞至 GetHierarchy] 方法 」 在 HierarchyScope 列舉指定擷取的筆記本結構的深度。 若要擷取中,除了筆記本的節,只要 HierarchyScope.hsSections 來更新這個列舉型別值,並處理其他 XML 子節點,為 的 圖 2 所示範。

圖 2 列舉區段

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.hsSections, 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);
      foreach (var sectionNode in from node in 
        notebookNode.Descendants(ns + "Section") select node)
      {
        Console.WriteLine("  " + sectionNode.Attribute("name").Value);
      }
    }
  }
}

正在擷取及更新頁面內容

GetPageContent 方法會傳回 XML 文件包含的所有內容,在指定的頁面上。 若要擷取頁面指定使用 OneNote 物件 ID,OneNote 筆記本階層架構中的每個物件,是以字串為基礎的唯一識別碼。 這個物件識別碼是作為 GetHierarchy 方法所傳回的 XML 節點上的屬性。

圖 3 建置在先前的範例使用 GetHierarchy 方法來擷取 OneNote 筆記本階層,向頁面範圍。 然後,它使用 LINQ to XML 選取名為 「 測試頁 」 頁面的節點,並將該頁面 ’s 物件 ID 傳遞至 GetPageContent 方法。 XML 文件,表示頁面內容接著會列印到主控台。

圖 3 取得頁面內容

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.hsPages, out notebookXml);

    var doc = XDocument.Parse(notebookXml);
    var ns = doc.Root.Name.Namespace;
    var pageNode = doc.Descendants(ns + "Page").Where(n => 
      n.Attribute("name").Value == "Test page").FirstOrDefault();
    if (pageNode != null)
    {
      string pageXml;
      onenoteApp.GetPageContent(pageNode.Attribute("ID").Value, out pageXml);
      Console.WriteLine(XDocument.Parse(pageXml));
    }
  }
}

UpdatePageContent 方法可用來對網頁進行變更。 網頁內容指定相同的 XML 文件結構描述的 的 圖 3 中的程式碼擷取 ; 它可以包含各種不同內容的項目定義文字外框]、 [插入的檔案]、 [影像]、 [筆跡],] 及 [音訊或視訊檔案。

UpdatePageContent 方法所提供的 XML 文件中將項目視為一系列可能已變更的內容、 比對指定的內容至現有的內容,透過其 OneNote 物件識別碼。 您可以因此變更現有內容呼叫 GetPageContent 方法,然後進行您想要的變更傳回,XML 再傳遞該 XML 回 UpdatePageContent 方法。 您也可以指定新的內容項目,以加入至頁面。

為了說明這, 的 圖 4,請加入我們的測試頁底部日期戳記。 它會使用 的 圖 3 所示的方法來判斷網頁,OneNote 物件識別碼,然後再使用中 System.Xml.Linq XDocument 和 XElement 類別建構 XML 文件包含新的內容。 因為文件中指定的頁面物件 ID 會找到物件識別碼的現有網頁 UpdatePageContent 方法會將新的內容附加到現有的網頁中。

圖 4 的 更新頁面內容

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.hsPages, out notebookXml);

    var doc = XDocument.Parse(notebookXml);
    var ns = doc.Root.Name.Namespace;
    var pageNode = doc.Descendants(ns + "Page").Where(n => 
      n.Attribute("name").Value == "Test page").FirstOrDefault();
    var existingPageId = pageNode.Attribute("ID").Value;

    if (pageNode != null)
    {
      var page = new XDocument(new XElement(ns + "Page", 
                                 new XElement(ns + "Outline", 
                                   new XElement(ns + "OEChildren", 
                                     new XElement(ns + "OE", 
                                       new XElement(ns + "T", 
                                         new XCData("Current date: " +
                                           DateTime.Now.
                                             ToLongDateString())))))));
       page.Root.SetAttributeValue("ID", existingPageId);
       onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue);
    }
  }
}

OneNote 物件模型程式庫

isn’t 特別難互動 OneNote 以此方式的資料,但 ’s 有點怪怪的剖析和建構 XML 文件,只是為了執行基本的資料作業。 ’s OneNote 物件模型會進來。 它 ’s Managed 程式碼程式庫,透過 COM 為基礎的 OneNote API 提供物件導向的抽象概念。 程式庫是開放原始碼和授權的 Microsoft 公用授權 (Ms PL) 下。

OneNote 的物件模型是可以在 onom.codeplex.com CodePlex 下載。 文件庫的設計,OneNote 2007,並依時間,您可以閱讀這,發行的下載項目應該會更新以提供 OneNote 2010 的相容性。 如果不是,您仍然可以使用它在 OneNote 2010 OneNote 2007 區段與下載來源的程式碼、 OneNoteCore 專案中移除現有的 Microsoft.Office.Interop.OneNote 組件參考和先前所示,加入 Microsoft OneNote 14.0 型別程式庫的參考。

除了一些單元測試專案和範例程式碼,方案包含兩個類別庫專案:OneNoteCore 和 OneNoteFramework。 OneNoteCore 程式庫是低階的橋接,OneNote COM API 和熟悉的 Microsoft.NET Framework 象徵物之間 ; 它會公開 參數 COM 而不是實際傳回值、 將 COM 錯誤代碼轉換成.NET 例外狀況、 公開 OneNoteObjectId 結構與 XDocument 執行個體,而非原始的字串和其他。 研究這個程式碼可以幫助您瞭解 OneNote API 的運作方式,但在大部分的情況下 won’t 需要直接互動 OneNoteCore 程式庫。

OneNoteFramework 程式庫會提供較高層級的 OneNote 概念的抽象概念。 您在這裡找到像 OneNoteNotebook、 OneNoteSection 和 OneNotePage 直覺式的名稱與類別。 主要的進入點,OneNote 的階層結構與互動是類別,稱為包含靜態成員呼叫目前的 OneNoteHierarchy。 加到 OneNoteFramework 程式庫組件參考我們可以重寫到我們的計畫列舉筆記本名稱 ( 的 圖 1) 更精確如下所示:

using Microsoft.Office.OneNote;

class Program
{
  static void Main(string[] args)
  {
    foreach (var notebook in OneNoteHierarchy.Current.Notebooks)
      System.Console.WriteLine(notebook.Name);
  }
}

如您所預期 OneNoteNotebook 類別具有名為區段的屬性。 因此,您可以列舉區段名稱 ( 的 圖 2) 只是如下所示:

using Microsoft.Office.OneNote;

class Program
{
  static void Main(string[] args)
  {
    foreach (var notebook in OneNoteHierarchy.Current.Notebooks)
    {
      System.Console.WriteLine(notebook.Name);
      foreach (var section in notebook.Sections)
      {
        System.Console.WriteLine("  " + section.Name);
      }
    }
  }
}

使用特殊的泛型集合類別,稱為 OneNoteObjectCollection <T> 管理公開的 OneNote 物件模型屬性的集合。 因為 OneNoteObjectCollection <T> 實作 IList <T>,如 IEnumerable <T>,可以使用 LINQ 查詢這些集合。

就例如區段變數中,給予 OneNoteSection 執行個體的參考,我們可以決定所有已使用像這樣的簡單 LINQ 運算式今天被修改的網頁:

var pagesModifiedToday = from page in section.Pages 
                           where page.LastModifiedTime >= DateTime.Today 
                           select page;

資料繫結與 OneNote 物件模型程式庫

OneNote 物件模型會公開 IEnumerable 集合的事實也可讓您以 XAML 為基礎的資料繫結與 Windows Presentation Foundation (WPF)。 圖 5 d 示範資料繫結至 XAML 標記中,純粹只是顯示的 OneNote 筆記本階層的 WPF 樹狀檢視的使用,而不需要程式碼後置的使用。

圖 5 資料繫結與 Windows Presentation Foundation

<Window x:Class="NotebookTree.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:onf="clr-namespace:Microsoft.Office.OneNote;assembly=
          OneNoteFramework"
        Title="OneNote Notebook Hierarchy" >
  <Grid>
    <Grid.Resources>
      <DataTemplate x:Key="PageTemplate">
        <StackPanel Orientation="Horizontal">
          <Image Source="Images\Page16.png" Margin="0,0,2,0"/>
          <TextBlock Text="{Binding Name}" />
        </StackPanel>
      </DataTemplate>
            
      <HierarchicalDataTemplate x:Key="SectionTemplate" 
        ItemsSource="{Binding Pages}"
        ItemTemplate="{StaticResource PageTemplate}">
        <StackPanel Orientation="Horizontal">
          <Image Source="Images\Section16.png" Margin="0,0,2,0"/>
          <TextBlock Text="{Binding Name}" />
        </StackPanel>
      </HierarchicalDataTemplate>
            
      <HierarchicalDataTemplate x:Key="NotebookTemplate" 
        ItemsSource="{Binding Sections}"
        ItemTemplate="{StaticResource SectionTemplate}">
        <StackPanel Orientation="Horizontal">
          <Image Source="Images\Book16.png" Margin="0,0,2,0"/>
          <TextBlock Text="{Binding Name}" />
        </StackPanel>
      </HierarchicalDataTemplate>
    </Grid.Resources>
        
    <TreeView Name="NotebookTree" BorderThickness="0"
              HorizontalAlignment="Left" VerticalAlignment="Top"
              ItemsSource="{Binding Notebooks}" 
              ItemTemplate="{StaticResource NotebookTemplate}" 
              DataContext="{Binding Source={x:Static 
                onf:OneNoteHierarchy.Current}}" />
  </Grid>
</Window>

此 XAML 第一次參考給它在 XML 命名空間前置詞 onf OneNoteFramework 組件。與此參考就地,樹狀檢視的 DataContext 可以再設定為 OneNoteHierarchy] 類別的靜態的目前屬性提供控制項使用 OneNote 的階層結構的根。HierarchicalDataTemplates 再用於資料繫結公開每個層級的樹狀目錄中,與對應的集合,由 OneNote 的物件模型 (請參閱 的 圖 6)。

圖 6 資料繫結至樹狀結構檢視階層

簡化的資料存取

完成,OneNote 物件模型程式庫大幅簡化存取 Microsoft OneNote 筆記本,公開 (Expose) 查詢和操作與 LINQ 運算式和 WPF 資料繫結的豐富的物件集合中的資料。待處理的文件會延伸到瀏覽使用 Silverlight] 和 [Windows 電話應用程式中的 OneNote 筆記本及存取在定域機組的 OneNote 資料這些概念。

Andy Gray 是協力廠商和技術的指導的 5 的才能軟體可協助非營利組織運作更有效率地透過策略性的技術解決方案。 他會寫入關於 OneNote 開發在 onenotedev.com

多虧了要檢閱這份文件的下列的技術專家:Michael GerfenJohn Guin.