21
Mar
2026

OneNote 插件开发

OneNote 插件开发笔记

最近在折腾 OneNote 插件开发,网上的资料特别少,绕了不少弯路,这里总结一下。


目录

  1. 环境要求
  2. 项目配置
  3. 代码规范
  4. 编译配置
  5. 注册表配置
  6. COM 注册步骤
  7. 常见问题排查
  8. 调试技巧

环境要求

必需软件

  • Visual Studio 2022(带 .NET Framework 4.8 SDK)
  • OneNote 桌面版(Office 365/2016/2019/2021)
  • .NET Framework 4.8(不能用 .NET Core 或 .NET 5+)

验证 OneNote 版本

OneNote -> File -> Account -> About OneNote

必须显示 32-bit 或 64-bit 桌面版,不能是 UWP 版或 Web 版。

验证 Office 架构

reg query "HKLM\SOFTWARE\Microsoft\Office\ClickToRun\Configuration" /v Platform

输出 x64 或 x86,决定 DLL 编译架构。


项目配置

创建项目

Visual Studio -> Create Project -> Class Library (.NET Framework),选 .NET Framework 4.8。

.csproj 关键配置

<PropertyGroup>
  <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
  <OutputType>Library</OutputType>
  <PlatformTarget>x64</PlatformTarget>
  <RegisterForComInterop>false</RegisterForComInterop>
</PropertyGroup>

COM 引用中 EmbedInteropTypes 必须设为 False:

  • Extensibility (GUID: AC0714F2-3D04-11D1-AE7D-00A0C90F26F4)
  • Microsoft.Office.Core (GUID: 2DF8D04C-5BFA-101B-BDE5-00AA0044DE52)
  • Microsoft.Office.Interop.OneNote (GUID: 0EA692EE-BB50-4E3C-AEF0-356D91732725)

AssemblyInfo.cs

[assembly: ComVisible(true)]
[assembly: CLSCompliant(true)]
[assembly: Guid("YOUR-GUID-HERE")]

代码规范

AddIn 主类

using System;
using Extensibility;
using Microsoft.Office.Core;

[ComVisible(true)]
[Guid("YOUR-GUID-HERE")]
[ProgId("YourAddIn.AddIn")]
[ClassInterface(ClassInterfaceType.None)]
public class AddIn : IDTExtensibility2, IRibbonExtensibility
{
    public AddIn() { }

    public void OnConnection(object Application,
        ext_ConnectMode ConnectMode, object AddInInst, ref Array custom) { }

    public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }

    public void OnAddInsUpdate(ref Array custom) { }
    public void OnStartupComplete(ref Array custom) { }
    public void OnBeginShutdown(ref Array custom) { }

    public string GetCustomUI(string RibbonID)
    {
        return Properties.Resources.ribbon;
    }
}

Ribbon XML

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" loadImage="GetImage">
  <ribbon>
    <tabs>
      <tab idMso="TabHome">
        <group id="groupTools" label="Tools">
          <button id="btnAction" label="Run" size="large" onAction="OnClick" />
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

编译与部署

msbuild YourProject.sln /p:Configuration=Release /p:Platform=x64

New-Item -ItemType Directory -Path "C:\Program Files\YourAddIn" -Force
Copy-Item "bind\Release\*.dll" "C:\Program Files\YourAddIn\" -Force

DLL 必须放 Program Files,用户目录会被 OneNote 拒载。


注册表配置

这是最关键的部分!

DllSurrogate(最重要)

[HKEY_CLASSES_ROOT\AppID\{YOUR-GUID}]
"DllSurrogate"=""

[HKEY_CLASSES_ROOT\CLSID\{YOUR-GUID}]
"AppID"="{YOUR-GUID}"

没有 DllSurrogate,OneNote 会静默拒绝加载 AddIn!

OneNote AddIn 注册表

[HKEY_CURRENT_USER\Software\Microsoft\Office\OneNote\AddIns\YourAddIn.AddIn]
"LoadBehavior"=dword:00000003
"FriendlyName"="YourAddIn"
"Description"="Your AddIn Description"
"CommandLineSafe"=dword:00000001

路径中不能包含版本号(如 16.0)!

COM 注册表

[HKEY_CLASSES_ROOT\CLSID\{YOUR-GUID}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="YourAddIn.AddIn"
"Assembly"="YourAddIn, Version=1.0.0.0"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Program Files/YourAddIn/YourAddIn.DLL"

COM 注册步骤

使用 regasm(注意匹配 Office 位数):

# 64 位 Office
$regasm = "C:\Windows\Microsoft.NET\Framework644.0.30319
egasm.exe"

# 反注册 -> 注册(带 /codebase)
& $regasm /unregister $dllPath
& $regasm /codebase /tlb $dllPath

# 添加 DllSurrogate
New-Item -Path "HKCR:\AppID\{YOUR-GUID}" -Force
New-ItemProperty -Path "HKCR:\AppID\{YOUR-GUID}" -Name "DllSurrogate" -Value "" -Force
New-ItemProperty -Path "HKCR:\CLSID\{YOUR-GUID}" -Name "AppID" -Value "{YOUR-GUID}" -Force

# 设置 OneNote AddIn
$path = "HKCU:\Software\Microsoft\Office\OneNote\AddIns\YourAddIn.AddIn"
New-Item -Path $path -Force
New-ItemProperty -Path $path -Name "LoadBehavior" -Value 3 -PropertyType DWord -Force
New-ItemProperty -Path $path -Name "FriendlyName" -Value "YourAddIn" -Force
New-ItemProperty -Path $path -Name "CommandLineSafe" -Value 1 -PropertyType DWord -Force

验证:

reg query "HKCR\CLSID\{YOUR-GUID}" /s
$com = New-Object -ComObject "YourAddIn.AddIn"

常见问题排查

AddIn 不显示

原因 方案
缺少 DllSurrogate 添加 DllSurrogate 注册表项
路径含版本号 去掉 16.0 等版本号
regasm 位数错 x64 Office 用 Framework64
DLL 在用户目录 移到 Program Files

LoadBehavior 3 -> 2

说明 OneNote 尝试加载但失败了。检查:

  1. Fusion 日志 (C:\FusionLogs)
  2. 事件查看器 (Windows Logs -> Application)
  3. DLL 依赖是否完整

代码签名

$cert = New-SelfSignedCertificate -Type CodeSigning -Subject "CN=Dev"
signtool.exe sign /a /fd SHA256 /tr http://timestamp.digicert.com "YourAddIn.dll"

调试技巧

Fusion 日志

reg add "HKLM\SOFTWARE\Microsoft\Fusion" /v EnableLog /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Microsoft\Fusion" /v LogPath /t REG_SZ /d "C:\FusionLogs" /f

内嵌日志

private static void Log(string msg) {
    File.AppendAllText(Path.Combine(Path.GetTempPath(), "AddIn.log"),
        $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {msg}
");
}

快速参考清单

阶段 检查项
编译前 .NET 4.8, x64/x86, ComVisible=true, ClassInterface=None
编译后 DLL->Program Files, Everyone Read, 代码签名
注册时 正确 regasm, /codebase, DllSurrogate, LoadBehavior=3
测试前 关 OneNote, 清 Wow6432Node, 验证 COM 创建

参考资料

上一篇:MiniMax 限时 9 折优惠 下一篇:Unclear Mind

评论列表:

发表评论: