清风小筑
聚合
软件开发技术
哲学(MindLogic)
摄影(Memory Of Lightwaves)
钢琴(Piano Stroies)
骑行(RideLife)
登录
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 架构 ```powershell 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 关键配置 ```xml <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 ```csharp [assembly: ComVisible(true)] [assembly: CLSCompliant(true)] [assembly: Guid("YOUR-GUID-HERE")] ``` --- ## 代码规范 ### AddIn 主类 ```csharp 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 ```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> ``` --- ## 编译与部署 ```powershell 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(最重要) ```ini [HKEY_CLASSES_ROOT\AppID\{YOUR-GUID}] "DllSurrogate"="" [HKEY_CLASSES_ROOT\CLSID\{YOUR-GUID}] "AppID"="{YOUR-GUID}" ``` 没有 DllSurrogate,OneNote 会静默拒绝加载 AddIn! ### OneNote AddIn 注册表 ```ini [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 注册表 ```ini [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 位数): ```powershell # 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 ``` 验证: ```powershell 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 依赖是否完整 ### 代码签名 ```powershell $cert = New-SelfSignedCertificate -Type CodeSigning -Subject "CN=Dev" signtool.exe sign /a /fd SHA256 /tr http://timestamp.digicert.com "YourAddIn.dll" ``` --- ## 调试技巧 ### Fusion 日志 ```powershell 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 ``` ### 内嵌日志 ```csharp 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 创建 | --- ## 参考资料 - [Microsoft Office COM Add-ins](https://docs.microsoft.com/en-us/office/dev/add-ins/) - [Regasm.exe](https://docs.microsoft.com/en-us/dotnet/framework/tools/regasm-exe-assembly-registration-tool) - [OneNote Add-in Development](https://docs.microsoft.com/en-us/office/dev/add-ins/onenote/onenote-add-ins)
标签:
Markdown
作者:
周遥(玄胤)
| 评论:0 | 浏览:
207
| 分类:
软件开发技术
上一篇:
MiniMax 限时 9 折优惠
下一篇:
Unclear Mind
评论列表:
发表评论:
点击这里取消回复
昵称
邮件地址 (选填)
个人主页 (选填)
链接
最新评论
周遥(玄胤):
@nanshanchxx:你这些问题应该...
小白:
法拉利老了也是法拉利,哈哈
nanshanchxx:
作者你好,试用了一下你的应用,感觉非常牛...
周遥(玄胤):
@伊基:开源 https://githu...
伊基:
你好,这个 RDP 客户端是开源的吗?如...
k:
我丢~还真是因为这个原因
网络小白:
膜拜大佬~
周遥(玄胤):
@广益-李华刚:IT 团队也归我管,这里...
广益-李华刚:
天哥,研究这个干嘛用
周遥(玄胤):
@ben:没有办法全部发,因为太多了,得...
评论列表: