This commit is contained in:
HuangHai
2026-01-24 15:44:20 +08:00
parent 16add651e2
commit 5e0fe0c628
75 changed files with 103673 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\WordAddIn.sln",
"PreviewInSolutionExplorer": false
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,89 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\dsWork\\aiData\\WordAddIn\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|d:\\dswork\\aidata\\wordaddin\\wordaddin\\airibbon.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\airibbon.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|D:\\dsWork\\aiData\\WordAddIn\\wordaddin\\airibbon.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\airibbon.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
},
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|D:\\dsWork\\aiData\\WordAddIn\\wordaddin\\loadingform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\loadingform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|D:\\dsWork\\aiData\\WordAddIn\\wordaddin\\loginform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\loginform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{3ae79031-e1bc-11d0-8f78-00a0c9110057}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "AiRibbon.cs",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.cs",
"RelativeDocumentMoniker": "WordAddIn\\AiRibbon.cs",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.cs",
"RelativeToolTip": "WordAddIn\\AiRibbon.cs",
"ViewState": "AgIAACgAAAAAAAAAAAAAACgAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-24T02:46:43.959Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "AiRibbon.xml",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.xml",
"RelativeDocumentMoniker": "WordAddIn\\AiRibbon.xml",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.xml",
"RelativeToolTip": "WordAddIn\\AiRibbon.xml",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003576|",
"WhenOpened": "2026-01-24T02:29:50.049Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "LoadingForm.cs",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoadingForm.cs",
"RelativeDocumentMoniker": "WordAddIn\\LoadingForm.cs",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoadingForm.cs",
"RelativeToolTip": "WordAddIn\\LoadingForm.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABsAAAAZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-24T02:08:22.195Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "LoginForm.cs",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoginForm.cs",
"RelativeDocumentMoniker": "WordAddIn\\LoginForm.cs",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoginForm.cs",
"RelativeToolTip": "WordAddIn\\LoginForm.cs",
"ViewState": "AgIAABsAAAAAAAAAAIAwwCYAAAAYAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-24T02:08:17.782Z"
}
]
}
]
}
]
}

View File

@@ -0,0 +1,89 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\dsWork\\aiData\\WordAddIn\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|d:\\dswork\\aidata\\wordaddin\\wordaddin\\airibbon.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\airibbon.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|D:\\dsWork\\aiData\\WordAddIn\\wordaddin\\airibbon.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\airibbon.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
},
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|D:\\dsWork\\aiData\\WordAddIn\\wordaddin\\loadingform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\loadingform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|D:\\dsWork\\aiData\\WordAddIn\\wordaddin\\loginform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}|WordAddIn\\WordAddIn.csproj|solutionrelative:wordaddin\\loginform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{3ae79031-e1bc-11d0-8f78-00a0c9110057}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "AiRibbon.cs",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.cs",
"RelativeDocumentMoniker": "WordAddIn\\AiRibbon.cs",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.cs",
"RelativeToolTip": "WordAddIn\\AiRibbon.cs",
"ViewState": "AgIAACgAAAAAAAAAAAAAACgAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-24T02:46:43.959Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "AiRibbon.xml",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.xml",
"RelativeDocumentMoniker": "WordAddIn\\AiRibbon.xml",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\AiRibbon.xml",
"RelativeToolTip": "WordAddIn\\AiRibbon.xml",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003576|",
"WhenOpened": "2026-01-24T02:29:50.049Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "LoadingForm.cs",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoadingForm.cs",
"RelativeDocumentMoniker": "WordAddIn\\LoadingForm.cs",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoadingForm.cs",
"RelativeToolTip": "WordAddIn\\LoadingForm.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABsAAAAZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-24T02:08:22.195Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "LoginForm.cs",
"DocumentMoniker": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoginForm.cs",
"RelativeDocumentMoniker": "WordAddIn\\LoginForm.cs",
"ToolTip": "D:\\dsWork\\aiData\\WordAddIn\\WordAddIn\\LoginForm.cs",
"RelativeToolTip": "WordAddIn\\LoginForm.cs",
"ViewState": "AgIAABsAAAAAAAAAAIAwwCYAAAAYAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-24T02:08:17.782Z"
}
]
}
]
}
]
}

BIN
WordAddIn/.vs/slnx.sqlite Normal file

Binary file not shown.

78
WordAddIn/Doc/步骤.md Normal file
View File

@@ -0,0 +1,78 @@
`Visual Studio 2022 Professional
下载地址:`visualstudio.microsoft.com`
安装器里务必勾选:
- 工作负载 → “.NET 桌面开发”
- 工作负载 → “Office/SharePoint 开发”
这两项会把 VSTO 项目模板、Office PIA(主互操作程序集)和调试工具一次装全
- Visual Studio 2022 Professional序列号:
```
TD244-P4NB7-YQ6XK-Y8MMM-YWV2J
```
验证步骤
1. 新建项目 → 语言选 C# → 搜索“VSTO”,能看到“Word 外接程序 (.NET Framework)”模板即成功 。
2. 直接 F5,Word 启动并在“加载项”页出现默认 Ribbon,说明调试环境就绪。
打包命令
msbuild WordAddIn.csproj /t:Publish /p:Configuration=Release
恭喜!既然程序已经开发完善,接下来就是激动人心的发布环节了。
要让其他人使用您的 Word 插件,最标准的方法是使用 Visual Studio 的**发布(Publish)**功能。这会生成一个安装程序( setup.exe ),用户只需双击即可自动配置环境并安装插件。
以下是详细的操作步骤:
### 第一步:准备发布信息
建议先完善一下软件的“身份信息”,这样安装界面会显得更专业:
1. 在 Visual Studio 右侧的 解决方案资源管理器 中,右键点击项目 WordAddIn ,选择 属性 (Properties) 。
2. 切换到 发布 (Publish) 选项卡。
3. 点击 选项 (Options) 按钮。
- 描述 (Description) :填写“发布者名称”(您的名字)和“产品名称”(如:AI 写作助手)。
- Office 设置 :保持默认即可。
4. 点击确定保存。
### 第二步:执行发布
1. 依然在 发布 (Publish) 选项卡页面。
2. 发布位置 :默认会发布到项目目录下的 publish\ 文件夹,或者您可以点击“浏览”选择一个桌面上的文件夹(例如 D:\Desktop\AIWordAddIn_Setup\ ),方便查找。
3. 点击页面底部的 立即发布 (Publish Now) 按钮。
4. Visual Studio 会开始编译并打包,成功后会自动打开生成的文件夹。
### 第三步:如何分享给他人
打开发布生成的文件夹,您会看到以下文件:
- 📂 Application Files (文件夹)
- 📄 setup.exe (安装程序)
- 📄 WordAddIn.vsto (部署清单)
分享方法 :
请将这个 文件夹内的所有内容 (包括文件夹和两个文件)一起打包压缩(例如 AI助手安装包.zip ),发送给您的朋友或用户。
### 第四步:对方如何安装(关键!)
由于我们使用的是开发用的“临时证书”(自签名证书),并没有购买昂贵的商业数字证书,所以对方在安装时,Windows 会提示“发布者不可信”并拦截安装。
请务必告诉您的朋友按以下步骤操作(只需做一次):
1. 解压 您发的压缩包。
2. 安装证书 (解决信任问题):
- 在文件夹中找到 WordAddIn.vsto 文件(或者是 WordAddIn_TemporaryKey.pfx ,如果在发布包里没包含 pfx,您可能需要单独发给他,或者指导他信任 setup.exe )。
- 更简单的测试方法 :通常直接运行 setup.exe ,如果报错说“证书不受信任”,则需要手动将证书添加到信任列表。
- 最稳妥的个人分发方式 :
1. 在您的电脑上,右键点击项目中的 WordAddIn_TemporaryKey.pfx -> 安装 PFX 。
2. 或者,让朋友在安装出错时,点击错误详情,选择“安装证书” -> 存储位置选 “受信任的根证书颁发机构” 。
如果觉得证书麻烦: 如果只是发给非常信任的朋友,且不想折腾证书,可以让他们:
1. 运行 setup.exe 。
2. 如果弹出红色警告,点击“详细信息”,查看是否允许“仍要运行”或“安装”。
### 总结
1. 右键项目 -> 发布 -> 立即发布 。
2. 把生成的文件夹打包发给别人。
3. 让对方运行 setup.exe 即可(注意解决证书信任警告)。
快去试试打包,把您的作品分享给第一个用户吧!

25
WordAddIn/WordAddIn.sln Normal file
View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36915.13 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WordAddIn", "WordAddIn\WordAddIn.csproj", "{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AA8EFE82-D53C-4781-B63A-98CE9009C192}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,838 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
using WordAddIn.Properties; // 引用 Properties 命名空间
namespace WordAddIn
{
[ComVisible(true)]
public class AiRibbon : Office.IRibbonExtensibility
{
private Office.IRibbonUI ribbon;
private AiService _aiService = new AiService();
private static bool _isLoggedIn = false; // 登录状态 (静态变量,确保整个应用程序生命周期内有效)
private string _documentContext = null; // 存储文档的全文分析上下文
private string _referenceContext = null; // 存储外部参考文档内容
private StyleProfile _styleProfile = null; // 存储文档的样式配置
public AiRibbon()
{
}
#region IRibbonExtensibility 成员
public string GetCustomUI(string ribbonID)
{
return GetResourceText("WordAddIn.AiRibbon.xml");
}
#endregion
#region Ribbon 回调
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
}
private string GetCombinedContext()
{
StringBuilder sb = new StringBuilder();
if (!string.IsNullOrWhiteSpace(_documentContext))
{
sb.AppendLine("【当前文档全文背景】:");
sb.AppendLine(_documentContext);
sb.AppendLine();
}
if (!string.IsNullOrWhiteSpace(_referenceContext))
{
sb.AppendLine("【外部参考资料】:");
sb.AppendLine(_referenceContext);
sb.AppendLine();
}
return sb.ToString();
}
public void OnImportReferenceClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Multiselect = true;
openFileDialog.Title = "补充背景 - 导入文档";
openFileDialog.Filter = "文档文件|*.docx;*.doc;*.txt|Word 文档|*.docx;*.doc|文本文件|*.txt|所有文件|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
StringBuilder sb = new StringBuilder();
int successCount = 0;
foreach (string file in openFileDialog.FileNames)
{
try
{
string ext = Path.GetExtension(file).ToLower();
string content = "";
if (ext == ".txt")
{
content = File.ReadAllText(file);
}
else if (ext == ".docx" || ext == ".doc")
{
dynamic wordApp = Globals.ThisAddIn.Application;
dynamic doc = wordApp.Documents.Open(FileName: file, Visible: false, ReadOnly: true, AddToRecentFiles: false);
content = doc.Content.Text;
doc.Close(SaveChanges: false);
}
if (!string.IsNullOrWhiteSpace(content))
{
sb.AppendLine($"--- 背景资料: {Path.GetFileName(file)} ---");
sb.AppendLine(content);
sb.AppendLine();
successCount++;
}
}
catch (Exception ex)
{
MessageBox.Show($"读取文件 {Path.GetFileName(file)} 失败: {ex.Message}");
}
}
_referenceContext = sb.ToString();
if (successCount > 0)
{
MessageBox.Show($"成功导入 {successCount} 个背景文档。\nAI 在后续的【智能扩写】、【润色加工】、【深度升华】等操作中将自动结合这些背景资料。");
}
}
}
}
public async void OnReadFullClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var doc = Globals.ThisAddIn.Application.ActiveDocument;
string fullText = doc.Content.Text;
if (string.IsNullOrWhiteSpace(fullText) || fullText.Length < 10)
{
MessageBox.Show("文档内容过少,无法进行有效分析。");
return;
}
loading = new LoadingForm("AI 正在通读全文并建立上下文,请稍候...");
loading.Show();
loading.Refresh();
// 限制长度防止 Token 溢出 (假设取前 20000 字符,通常足够分析风格)
if (fullText.Length > 20000)
{
fullText = fullText.Substring(0, 20000);
}
// 1. 语义分析
_documentContext = await Task.Run(() => _aiService.AnalyzeDocument(fullText));
if (!string.IsNullOrEmpty(_documentContext))
{
MessageBox.Show($"通读完成!\n\n【文档分析结果】:\n{_documentContext}\n\n后续的“智能扩写”与“素材写作”将自动应用此上下文信息。", "AI 助手");
}
}
catch (Exception ex)
{
MessageBox.Show("全文分析失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
public async void OnPolishClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var selection = Globals.ThisAddIn.Application.Selection;
// 1. 判断是否有选中文本
bool hasSelection = selection.Type == Word.WdSelectionType.wdSelectionNormal ||
(!string.IsNullOrEmpty(selection.Text) && selection.Text.Length > 1);
if (!hasSelection)
{
// 2. 尝试从剪贴板读取
IDataObject data = Clipboard.GetDataObject();
if (data != null && data.GetDataPresent(DataFormats.Text))
{
string clipboardText = (string)data.GetData(DataFormats.Text);
if (!string.IsNullOrWhiteSpace(clipboardText))
{
// 询问用户是否要润色剪贴板内容
// 简单起见,如果没选中文字,默认就是处理剪贴板(类似扩写逻辑)
// 但为了避免误操作,我们可以提示一下?
// 扩写逻辑是直接把剪贴板当 originalText,生成后插入光标处。
// 润色通常是“替换”原文。如果是剪贴板,那就是“插入润色后的内容”。
// 逻辑一致。
}
else
{
MessageBox.Show("剪贴板中内容为空,请先选择一段需要润色的文字,或者复制文字到剪贴板。");
return;
}
}
else
{
MessageBox.Show("请先选择一段需要润色的文字,或者复制文字到剪贴板。");
return;
}
}
string originalText;
if (hasSelection)
{
originalText = selection.Text.Trim();
}
else
{
IDataObject data = Clipboard.GetDataObject();
originalText = (string)data.GetData(DataFormats.Text);
}
if (string.IsNullOrWhiteSpace(originalText))
{
MessageBox.Show("获取文字失败,请重试。");
return;
}
// 显示加载窗体
loading = new LoadingForm("AI 正在润色加工中,请稍候...");
loading.Show();
loading.Refresh();
// 在后台线程运行 AI 请求
string polishedText = await Task.Run(() => _aiService.PolishText(originalText, GetCombinedContext()));
if (!string.IsNullOrEmpty(polishedText))
{
SmartInsert(selection, polishedText);
}
}
catch (Exception ex)
{
MessageBox.Show("润色失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
public async void OnElevateClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var selection = Globals.ThisAddIn.Application.Selection;
// 1. 判断是否有选中文本
bool hasSelection = selection.Type == Word.WdSelectionType.wdSelectionNormal ||
(!string.IsNullOrEmpty(selection.Text) && selection.Text.Length > 1);
if (!hasSelection)
{
IDataObject data = Clipboard.GetDataObject();
if (data != null && data.GetDataPresent(DataFormats.Text))
{
string clipboardText = (string)data.GetData(DataFormats.Text);
if (string.IsNullOrWhiteSpace(clipboardText))
{
MessageBox.Show("剪贴板中内容为空,请先选择一段需要升华的文字,或者复制文字到剪贴板。");
return;
}
}
else
{
MessageBox.Show("请先选择一段需要升华的文字,或者复制文字到剪贴板。");
return;
}
}
string originalText;
if (hasSelection)
{
originalText = selection.Text.Trim();
}
else
{
IDataObject data = Clipboard.GetDataObject();
originalText = (string)data.GetData(DataFormats.Text);
}
if (string.IsNullOrWhiteSpace(originalText))
{
MessageBox.Show("获取文字失败,请重试。");
return;
}
// 显示加载窗体
loading = new LoadingForm("AI 正在深度升华中,挖掘核心价值...");
loading.Show();
loading.Refresh();
// 在后台线程运行 AI 请求
string elevatedText = await Task.Run(() => _aiService.ElevateText(originalText, GetCombinedContext()));
if (!string.IsNullOrEmpty(elevatedText))
{
SmartInsert(selection, elevatedText);
}
}
catch (Exception ex)
{
MessageBox.Show("升华失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
public async void OnExpandClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var selection = Globals.ThisAddIn.Application.Selection;
// 1. 判断是否有选中文本
bool hasSelection = selection.Type == Word.WdSelectionType.wdSelectionNormal ||
(!string.IsNullOrEmpty(selection.Text) && selection.Text.Length > 1);
if (!hasSelection)
{
// 2. 尝试从剪贴板读取
IDataObject data = Clipboard.GetDataObject();
if (data != null && data.GetDataPresent(DataFormats.Text))
{
string clipboardText = (string)data.GetData(DataFormats.Text);
if (!string.IsNullOrWhiteSpace(clipboardText))
{
// 将剪贴板内容插入文档,并选中它作为待扩写内容
selection.Range.Text = clipboardText;
// 重新获取 selection,确保包含刚插入的文本
// 注意:赋值 Range.Text 后,selection 通常会变成插入文本后的光标,或者选中插入文本
// 我们显式选中刚才插入的范围比较稳妥
// 但简化处理,直接让用户确认是否扩写刚才粘贴的内容
// 这里 selection.Text = clipboardText 会替换光标或选区
// 此时 selection 可能位于文本末尾。
// 为了扩写,我们需要选中这段新文本。
// 简单起见,我们直接把 clipboardText 作为 originalText 传给 AI,
// 但回写时需要知道覆盖哪里。
// 最好的方式是:先插入,让 Selection 包含这段文字。
// 实际上 Word 的 Selection.Text = "xxx" 后,Selection 会变成折叠状态在文字后面。
// 所以我们需要倒推回去选中它。
// 或者,我们可以直接记录 Range。
// 修正策略:直接用 clipboardText 发给 AI,
// 然后生成完后,直接在这个位置插入(Selection 还在原处或刚插入文本的后面)。
// 但原来的逻辑是 selection.Text = expandedText (替换)。
// 如果我刚才没插入,现在插入 expandedText 也是对的。
// 唯一的问题是:加载动画期间,用户看不到原文。
// 但这也许是好事?直接变身。
// 让我们采用“直接替换”逻辑,不先插入原文。
// 但等等,如果是“扩写”,通常是基于原文。
// 如果不插入,用户就没法在扩写前对原文做微调(虽然现在的流程也不支持微调)。
// 既然用户点击了按钮,就是想一步到位。
// 所以:如果没选中,就假装选中了剪贴板内容。
// originalText = clipboardText
// 后面 selection.Text = expandedText 会直接在光标处插入扩写后的内容。
// 完美。
// 唯一例外:如果 selection 是光标,selection.Text = expandedText 会插入。
// 此时 originalText = clipboardText.
}
else
{
MessageBox.Show("剪贴板中内容为空,请先选择一段需要扩写的文字,或者复制文字到剪贴板。");
return;
}
}
else
{
MessageBox.Show("请先选择一段需要扩写的文字,或者复制文字到剪贴板。");
return;
}
}
// 此时 selection.Text 可能为空(如果是剪贴板模式),
// 所以我们不能再依赖 selection.Text.Trim() 作为 originalText
// 我们需要一个变量来持有它。
string originalText;
if (hasSelection)
{
originalText = selection.Text.Trim();
}
else
{
// 再次获取,确保逻辑严谨(虽然上面已经 check 过了)
IDataObject data = Clipboard.GetDataObject();
originalText = (string)data.GetData(DataFormats.Text);
}
if (string.IsNullOrWhiteSpace(originalText))
{
MessageBox.Show("获取文字失败,请重试。");
return;
}
// 弹出选项设置窗体
string customPrompt = null;
using (var optionsForm = new ExpandOptionsForm())
{
if (optionsForm.ShowDialog() != DialogResult.OK)
{
return; // 用户取消
}
customPrompt = optionsForm.SelectedPrompt;
}
// 显示加载窗体
loading = new LoadingForm("AI 正在扩写中,请稍候...");
loading.Show();
loading.Refresh(); // 强制重绘
// 在后台线程运行 AI 请求,防止阻塞 UI
string expandedText = await Task.Run(() => _aiService.ExpandText(originalText, customPrompt, GetCombinedContext()));
if (!string.IsNullOrEmpty(expandedText))
{
// 使用智能插入代替直接赋值
SmartInsert(selection, expandedText);
}
}
catch (Exception ex)
{
MessageBox.Show("扩写失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
public async void OnReferenceGenerateClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var selection = Globals.ThisAddIn.Application.Selection;
string originalText = selection.Text; // 可以为空
string referenceContent = null;
int wordLimit = 500;
using (var form = new ReferenceGeneratorForm())
{
if (form.ShowDialog() != DialogResult.OK)
{
return;
}
wordLimit = form.WordLimit;
if (form.IsFileMode)
{
string path = form.SelectedFilePath;
string ext = Path.GetExtension(path).ToLower();
if (ext == ".txt")
{
referenceContent = File.ReadAllText(path);
}
else
{
// 尝试用 Word 打开
try
{
// 使用 dynamic 避免繁琐的 ref object
dynamic wordApp = Globals.ThisAddIn.Application;
dynamic doc = wordApp.Documents.Open(FileName: path, Visible: false, ReadOnly: true, AddToRecentFiles: false);
referenceContent = doc.Content.Text;
doc.Close(SaveChanges: false);
}
catch (Exception ex)
{
MessageBox.Show($"读取文档失败: {ex.Message}");
return;
}
}
}
else
{
referenceContent = form.ReferenceContent;
}
}
if (string.IsNullOrWhiteSpace(referenceContent))
{
MessageBox.Show("素材内容为空,无法生成。");
return;
}
loading = new LoadingForm("AI 正在进行素材写作,请稍候...");
loading.Show();
loading.Refresh();
string result = await Task.Run(() => _aiService.GenerateWithReference(originalText, referenceContent, wordLimit, GetCombinedContext()));
if (!string.IsNullOrEmpty(result))
{
// 使用智能插入代替直接赋值
SmartInsert(selection, result);
}
}
catch (Exception ex)
{
MessageBox.Show("生成失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
private void SmartInsert(Word.Selection selection, string text)
{
try
{
// 简化逻辑:直接使用 TypeText 插入,让 Word 自动应用当前光标位置的格式
// 这样可以最大程度保持与原文格式一致(兼容性最好)
// 同时也避免了手动应用样式带来的偏差
// 如果是覆盖选区,先检查是否需要清空(TypeText 会自动替换选区,但显式处理更清晰)
// selection.TypeText(text); // 这就足够了
// 2024-01-24 修正:用户反馈格式偏差大,且不希望 Markdown。
// 因此我们不再进行 Markdown 解析,也不再强制应用 StyleProfile 中的样式。
// 直接插入纯文本,让 Word 处理。
selection.TypeText(text);
}
catch (Exception ex)
{
// 出错时回退到简单赋值
selection.Text = text;
Console.WriteLine("Smart insert failed: " + ex.Message);
}
}
public async void OnFormatClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var doc = Globals.ThisAddIn.Application.ActiveDocument;
string fullText = doc.Content.Text;
if (string.IsNullOrWhiteSpace(fullText) || fullText.Length < 10)
{
MessageBox.Show("文档内容过少,无法进行格式美化。");
return;
}
// 限制长度防止 Token 溢出
if (fullText.Length > 20000)
{
fullText = fullText.Substring(0, 20000);
}
loading = new LoadingForm("AI 正在分析文档结构并进行格式美化...");
loading.Show();
loading.Refresh();
// 1. AI 分析结构
var headings = await Task.Run(() => _aiService.AnalyzeStructure(fullText));
// 即使 headings 为空,我们也要继续处理正文缩进,所以这里不再直接 return
if (headings == null)
{
headings = new List<WordAddIn.AiService.HeadingInfo>();
// MessageBox.Show("未识别到有效的标题结构。"); // 可以不提示,静默处理
}
// 2. 应用样式 (在 UI 线程)
int changeCount = 0;
int indentCount = 0;
foreach (Word.Paragraph p in doc.Paragraphs)
{
string pText = p.Range.Text.Trim();
if (string.IsNullOrWhiteSpace(pText)) continue;
// 查找匹配的标题
// AI 返回的 text 可能不包含序号,或者有微小差异。
// 使用 Contains 匹配比较宽容
var match = headings.FirstOrDefault(h => pText.Contains(h.text));
if (match != null)
{
Word.WdBuiltinStyle styleEnum = Word.WdBuiltinStyle.wdStyleNormal;
switch (match.level)
{
case 1: styleEnum = Word.WdBuiltinStyle.wdStyleHeading1; break;
case 2: styleEnum = Word.WdBuiltinStyle.wdStyleHeading2; break;
case 3: styleEnum = Word.WdBuiltinStyle.wdStyleHeading3; break;
case 4: styleEnum = Word.WdBuiltinStyle.wdStyleHeading4; break;
case 5: styleEnum = Word.WdBuiltinStyle.wdStyleHeading5; break;
default: styleEnum = Word.WdBuiltinStyle.wdStyleHeading1; break;
}
p.set_Style(styleEnum);
// 标题通常不需要首行缩进(或者由样式决定),这里显式清除手动缩进,以防万一
p.Format.CharacterUnitFirstLineIndent = 0;
p.Format.FirstLineIndent = 0;
changeCount++;
}
else
{
// 正文段落:设置首行缩进2字符
p.Format.CharacterUnitFirstLineIndent = 2;
indentCount++;
}
}
string msg = $"格式美化完成!\n- 已调整 {changeCount} 处标题格式。";
if (indentCount > 0)
{
msg += $"\n- 已对 {indentCount} 个段落应用首行缩进。";
}
MessageBox.Show(msg);
}
catch (Exception ex)
{
MessageBox.Show("格式美化失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
public async void OnImageClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var selection = Globals.ThisAddIn.Application.Selection;
string prompt = selection.Text;
if (string.IsNullOrWhiteSpace(prompt))
{
MessageBox.Show("请先选择一段描述图片的文字。");
return;
}
// 弹出图片风格设置窗体
string style = null;
string additionalPrompt = null;
using (var imgOptions = new ImageOptionsForm())
{
if (imgOptions.ShowDialog() != DialogResult.OK)
{
return; // 用户取消
}
style = imgOptions.SelectedStyle;
additionalPrompt = imgOptions.AdditionalPrompt;
}
// 组合 Prompt
if (!string.IsNullOrWhiteSpace(additionalPrompt))
{
prompt += $"\n补充要求: {additionalPrompt}";
}
loading = new LoadingForm("AI 正在绘制图片,请稍候...");
loading.Show();
loading.Refresh();
// 传入 style 参数
string imageUrl = await Task.Run(() => _aiService.GenerateImageUrl(prompt, style));
if (!string.IsNullOrEmpty(imageUrl))
{
InsertImageFromUrl(imageUrl);
}
else
{
MessageBox.Show("未生成图片 URL。");
}
}
catch (Exception ex)
{
MessageBox.Show("图片生成失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
public void OnSettingsClick(Office.IRibbonControl control)
{
MessageBox.Show("请在代码 AiService.cs 中配置您的 API Key。", "设置");
}
#endregion
#region 帮助器
private bool EnsureLoggedIn()
{
if (_isLoggedIn) return true;
using (var loginForm = new LoginForm())
{
if (loginForm.ShowDialog() == DialogResult.OK)
{
_isLoggedIn = true;
return true;
}
}
return false;
}
private void InsertImageFromUrl(string imageUrl)
{
string tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".png");
try
{
using (WebClient client = new WebClient())
{
client.DownloadFile(imageUrl, tempFile);
}
var selection = Globals.ThisAddIn.Application.Selection;
// 移动到选区末尾插入,避免覆盖文字
selection.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
selection.TypeParagraph(); // 将图片嵌入文档
var inlineShape = selection.InlineShapes.AddPicture(tempFile, LinkToFile: false, SaveWithDocument: true);
// 自动调整图片大小为页面宽度的 80% (留出一点边距更美观)
try
{
var pageSetup = selection.PageSetup;
float pageWidth = pageSetup.PageWidth;
float leftMargin = pageSetup.LeftMargin;
float rightMargin = pageSetup.RightMargin;
// 有效内容宽度
float contentWidth = pageWidth - leftMargin - rightMargin;
// 设置图片宽度 (如果图片本身小于页面宽度,也可以选择不放大,这里强制设为 100% 宽度)
inlineShape.Width = contentWidth;
// 保持纵横比
inlineShape.LockAspectRatio = Microsoft.Office.Core.MsoTriState.msoTrue;
}
catch
{
// 如果获取页面设置失败,给一个默认值 (500磅,约17.6cm,接近A4宽度)
inlineShape.Width = 500;
}
}
catch (Exception ex)
{
throw new Exception("图片下载或插入失败: " + ex.Message);
}
finally
{
if (File.Exists(tempFile))
{
try { File.Delete(tempFile); } catch { }
}
}
}
private static string GetResourceText(string resourceName)
{
Assembly asm = Assembly.GetExecutingAssembly();
string[] resourceNames = asm.GetManifestResourceNames();
for (int i = 0; i < resourceNames.Length; ++i)
{
if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
{
using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
{
if (resourceReader != null)
{
return resourceReader.ReadToEnd();
}
}
}
}
return null;
}
#endregion
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
<ribbon>
<tabs>
<tab id="tabAiAssistant" label="AI助手">
<group id="groupContent" label="内容创作">
<button id="btnReadFull" label="通读全文" size="large" onAction="OnReadFullClick" imageMso="FindDialog" />
<button id="btnImportReference" label="补充背景" size="large" onAction="OnImportReferenceClick" imageMso="ImportTextFile" />
<button id="btnReferenceGenerate" label="素材写作" size="large" onAction="OnReferenceGenerateClick" imageMso="ReviewCompareTwoVersions" />
<button id="btnPolish" label="润色加工" size="large" onAction="OnPolishClick" imageMso="Spelling" />
<button id="btnElevate" label="深度升华" size="large" onAction="OnElevateClick" imageMso="SmartArtInsert" />
<button id="btnExpand" label="智能扩写" size="large" onAction="OnExpandClick" imageMso="ReviewNewComment" />
<button id="btnFormat" label="格式美化" imageMso="FontColorCycle" size="large" onAction="OnFormatClick" />
<button id="btnImage" label="生成配图" size="large" onAction="OnImageClick" imageMso="PictureInsertFromFile" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>

View File

@@ -0,0 +1,308 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WordAddIn.Models;
namespace WordAddIn
{
public class AiService
{
// 兔子平台配置
private const string ApiKey = "sk-FCwlaMANKdSlXlY7HkzZncSp0N5gecfpQdk0iR059Hfk4dQ1";
private const string BaseUrl = "https://api.tu-zi.com/v1";
// 模型配置
private const string TextModel = "gemini-3-flash-preview";
private const string ImageModel = "gemini-3-pro-image-preview";
private static readonly HttpClient _httpClient;
static AiService()
{
// 必须强制启用 TLS 1.2,否则无法连接现代 HTTPS 站点
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
_httpClient = new HttpClient();
_httpClient.Timeout = TimeSpan.FromSeconds(60);
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
}
public async Task<string> ExpandText(string originalText, string customInstruction = null, string documentContext = null)
{
string instruction = string.IsNullOrWhiteSpace(customInstruction)
? "请将以下内容扩写成一段正式、通顺的段落,保持原意但增加细节"
: customInstruction;
string systemPrompt = "你是一个专业的文档编辑助手。请直接输出扩写后的纯文本内容,不要使用任何Markdown标记(如#、**、- 等)。直接使用自然段落。";
if (!string.IsNullOrWhiteSpace(documentContext))
{
systemPrompt += $"\n\n【全文背景与排版规则】:你已通读全文,以下是文档的整体上下文信息和排版规则,请在扩写时保持与全文主题和风格的一致性,并参考排版规则生成对应的层级结构:\n{documentContext}";
}
var messages = new List<Message>
{
new Message { role = "system", content = systemPrompt },
new Message { role = "user", content = $"{instruction}:\n\n{originalText}" }
};
return await GetChatCompletion(messages);
}
public async Task<string> PolishText(string originalText, string documentContext = null)
{
string systemPrompt = "你是一个专业的文字编辑和润色专家。请对用户提供的文本进行深度润色和梳理。目标是:1. 提升语言的流畅度和专业性;2. 修正语法错误和用词不当;3. 优化逻辑结构,使表达更清晰;4. 保持原意不变。请直接输出润色后的内容,不要包含任何解释或客套话。请直接输出纯文本,不要使用任何Markdown标记。";
if (!string.IsNullOrWhiteSpace(documentContext))
{
systemPrompt += $"\n\n【全文背景与排版规则】:你已通读全文,以下是文档的整体上下文信息和排版规则,请在润色时保持与全文主题和风格的一致性,并参考排版规则生成对应的层级结构:\n{documentContext}";
}
var messages = new List<Message>
{
new Message { role = "system", content = systemPrompt },
new Message { role = "user", content = $"请润色以下内容:\n\n{originalText}" }
};
return await GetChatCompletion(messages);
}
public async Task<string> ElevateText(string originalText, string documentContext = null)
{
string systemPrompt = "你是一个资深的领域专家和思想家。用户提供了一段文本,请你根据自己的广博知识和深刻理解,对其进行深度升华。目标是:1. 挖掘深度:透过现象看本质,补充更有见地的分析;2. 拓展广度:引入相关的行业背景、前沿趋势或跨学科视角;3. 提升价值:将普通的描述提升为具有指导意义或启发性的洞见;4. 高于原文:不要局限于原文的字面意思,要大胆进行思想层面的拔高。请直接输出升华后的纯文本内容,保持逻辑连贯,不要使用任何Markdown标记。";
if (!string.IsNullOrWhiteSpace(documentContext))
{
systemPrompt += $"\n\n【全文背景与排版规则】:你已通读全文,以下是文档的整体上下文信息和排版规则,请在升华时保持与全文主题和风格的一致性(但在思想深度上要超越它),并参考排版规则生成对应的层级结构:\n{documentContext}";
}
var messages = new List<Message>
{
new Message { role = "system", content = systemPrompt },
new Message { role = "user", content = $"请对以下内容进行深度升华和价值提升:\n\n{originalText}" }
};
return await GetChatCompletion(messages);
}
public async Task<string> GenerateWithReference(string originalText, string referenceContent, int wordLimit, string documentContext = null)
{
string systemPrompt = "你是一个专业的文档写作助手。请根据提供的参考资料,撰写或重写目标文本。请直接输出纯文本内容,不要使用任何Markdown标记。";
if (!string.IsNullOrWhiteSpace(documentContext))
{
systemPrompt += $"\n\n【全文背景与排版规则】:你已通读全文,以下是文档的整体上下文信息和排版规则,请在生成时保持与全文主题和风格的一致性,并参考排版规则生成对应的层级结构:\n{documentContext}";
}
StringBuilder userPrompt = new StringBuilder();
userPrompt.AppendLine("请根据以下信息生成内容:");
userPrompt.AppendLine();
userPrompt.AppendLine($"【字数要求】:{wordLimit}字左右");
userPrompt.AppendLine();
if (!string.IsNullOrWhiteSpace(referenceContent))
{
userPrompt.AppendLine("【参考资料】:");
userPrompt.AppendLine(referenceContent);
userPrompt.AppendLine();
}
if (!string.IsNullOrWhiteSpace(originalText))
{
userPrompt.AppendLine("【目标文本/上下文】:");
userPrompt.AppendLine(originalText);
userPrompt.AppendLine();
}
userPrompt.AppendLine("请开始生成:");
var messages = new List<Message>
{
new Message { role = "system", content = systemPrompt },
new Message { role = "user", content = userPrompt.ToString() }
};
return await GetChatCompletion(messages);
}
public async Task<List<HeadingInfo>> AnalyzeStructure(string text)
{
string systemPrompt = @"你是一个文档格式专家。请分析用户提供的文档内容,识别出所有的标题及其对应的层级(1级、2级、3级...)。
请只返回一个JSON数组,数组中的每个元素包含 'text' (标题所在行的完整纯文本内容,包含序号) 和 'level' (整数层级)。
忽略正文内容,只提取标题。
例如:[{""text"": ""第一章 绪论"", ""level"": 1}, {""text"": ""1.1 研究背景"", ""level"": 2}]
请确保返回的是合法的JSON格式,不包含Markdown标记。";
var messages = new List<Message>
{
new Message { role = "system", content = systemPrompt },
new Message { role = "user", content = text }
};
string jsonResponse = await GetChatCompletion(messages);
// 清理可能存在的 Markdown 代码块标记
jsonResponse = jsonResponse.Replace("```json", "").Replace("```", "").Trim();
try
{
return JsonConvert.DeserializeObject<List<HeadingInfo>>(jsonResponse);
}
catch (Exception ex)
{
Console.WriteLine("JSON Parsing Failed: " + ex.Message);
return new List<HeadingInfo>();
}
}
public class HeadingInfo
{
public string text { get; set; }
public int level { get; set; }
}
public async Task<string> AnalyzeDocument(string fullText)
{
var messages = new List<Message>
{
new Message { role = "system", content = "你是一个文档分析专家。请阅读提供的文档全文,并提取关键的上下文信息,包括:1. 核心主题摘要;2. 写作风格与语调;3. 关键术语或背景设定。请生成一段简明扼要的“文档画像”,用于在后续写作任务中作为System Prompt的一部分,帮助AI保持上下文一致性。请直接输出这段描述性文字,不要包含其他客套话。" },
new Message { role = "user", content = $"请分析以下文档全文:\n\n{fullText}" }
};
return await GetChatCompletion(messages);
}
public async Task<string> FormatText(string originalText)
{
var messages = new List<Message>
{
new Message { role = "system", content = "你是一个文档排版专家。请直接输出处理后的纯文本,严禁使用Markdown格式,不要包含任何解释性文字。" },
new Message { role = "user", content = $"请对以下文本进行格式化和润色:修正错别字、规范标点符号、优化分段,使其看起来更专业:\n\n{originalText}" }
};
return await GetChatCompletion(messages);
}
public async Task<string> GenerateImageUrl(string prompt, string style = null)
{
try
{
// 1. 优化 Prompt:将用户输入转换为安全的英文绘图 Prompt,并注入风格
string optimizedPrompt = await OptimizePromptForImage(prompt, style);
// 使用匿名对象以获得最大灵活性
var requestBody = new
{
prompt = optimizedPrompt,
model = ImageModel,
size = "1024x1024",
response_format = "url" // 显式请求 URL 格式
};
var json = JsonConvert.SerializeObject(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{BaseUrl}/images/generations", content);
var responseString = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new Exception($"API Error ({response.StatusCode}): {responseString}");
}
// 使用 JObject 动态解析
var jsonResponse = JObject.Parse(responseString);
// 1. 尝试解析标准格式: data[0].url
var data = jsonResponse["data"];
if (data != null)
{
if (data.Type == JTokenType.Array && data.HasValues)
{
var firstItem = data[0];
// Gemini 3 image preview 可能会返回 revised_prompt 和 url
if (firstItem["url"] != null) return firstItem["url"].ToString();
// 有时它会返回 NO_IMAGE,这可能是模型拒绝了,或者格式不对
if (firstItem["revised_prompt"] != null && firstItem["revised_prompt"].ToString() == "NO_IMAGE")
{
// 尝试从其他字段找,或者这就是个错误
// 如果是 NO_IMAGE,通常意味着内容安全拦截或生成失败
// 但这里我们先假设它可能在别的字段
}
// 某些 API 可能直接在数组里放 URL 字符串
if (firstItem.Type == JTokenType.String) return firstItem.ToString();
}
// 2. 尝试解析 data 为直接字符串的情况
else if (data.Type == JTokenType.String)
{
return data.ToString();
}
}
// 3. 尝试解析根节点 url
if (jsonResponse["url"] != null)
{
return jsonResponse["url"].ToString();
}
throw new Exception($"无法从响应中解析图片 URL。原始响应: {responseString}");
}
catch (Exception ex)
{
throw new Exception($"生图请求失败: {ex.Message}", ex);
}
}
private async Task<string> OptimizePromptForImage(string originalPrompt, string style = null)
{
string styleInstruction = string.IsNullOrEmpty(style) ? "" : $"6. 图片风格必须严格遵循:{style}。";
var messages = new List<Message>
{
new Message { role = "system", content = $"你是一个专业的AI绘图提示词专家。你的任务是将用户的输入转化为一段高质量的、英文的DALL-E 3绘图提示词。请遵循以下规则:\n1. 描述画面的部分必须翻译成英文。\n2. 提炼核心意象,去除无关的修饰语或敏感词。\n3. 增加艺术风格、光影、构图等细节描述。\n4. 直接输出最终的英文Prompt,不要包含任何解释或前言后语。\n5. 确保内容安全,符合通用内容审核标准。\n{styleInstruction}\n7. 【重要约束】如果画面中需要包含任何文字(Text/Label/Title),必须严格保留中文(Simplified Chinese),并明确指示 'text in Chinese',绝对禁止在画面中生成英文文字。" },
new Message { role = "user", content = $"请根据以下描述生成一段绘图Prompt:\n{originalPrompt}" }
};
return await GetChatCompletion(messages);
}
private async Task<string> GetChatCompletion(List<Message> messages)
{
try
{
var requestBody = new ChatCompletionRequest
{
messages = messages,
model = TextModel
};
var json = JsonConvert.SerializeObject(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{BaseUrl}/chat/completions", content);
var responseString = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new Exception($"API Error ({response.StatusCode}): {responseString}");
}
var result = JsonConvert.DeserializeObject<ChatCompletionResponse>(responseString);
return result?.choices?.FirstOrDefault()?.message?.content;
}
catch (Exception ex)
{
// 抛出更详细的错误
throw new Exception($"AI 请求失败: {ex.Message}", ex);
}
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WordAddIn
{
public class ExpandOptionsForm : Form
{
public string SelectedPrompt { get; private set; }
private ComboBox cmbTemplates;
private TextBox txtCustomPrompt;
private Button btnOk;
private Button btnCancel;
private readonly Dictionary<string, string> _templates = new Dictionary<string, string>
{
{ "默认扩写", "请将以下内容扩写成一段正式、通顺的段落,保持原意但增加细节。" },
{ "细腻情感", "请对选中文本进行扩写,重点从心理活动、情绪变化和感官体验三个维度进行细腻描写。" },
{ "商务正式", "请将选中文本改写为商务职场风格,使用专业术语,语气正式且客观。" },
{ "生动故事", "请将选中文本扩写为一个生动的小故事,增加对话和场景描写,使其引人入胜。" },
{ "学术严谨", "请将选中文本扩写为学术风格,逻辑严密,用词精准,适合用于论文或报告。" },
{ "诗意唯美", "请用优美、诗意的语言扩写选中文本,多用修辞手法,营造唯美的意境。" }
};
public ExpandOptionsForm()
{
InitializeComponent();
InitializeTemplates();
}
private void InitializeComponent()
{
this.Text = "智能扩写设置";
this.Size = new Size(500, 350);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
// Labels
var lblTemplate = new Label { Text = "选择预设模板:", Location = new Point(20, 20), AutoSize = true };
var lblCustom = new Label { Text = "扩写要求 (可修改):", Location = new Point(20, 80), AutoSize = true };
// ComboBox
cmbTemplates = new ComboBox { Location = new Point(20, 45), Width = 440, DropDownStyle = ComboBoxStyle.DropDownList };
cmbTemplates.SelectedIndexChanged += CmbTemplates_SelectedIndexChanged;
// TextBox
txtCustomPrompt = new TextBox { Location = new Point(20, 105), Width = 440, Height = 120, Multiline = true, ScrollBars = ScrollBars.Vertical };
// Buttons
btnOk = new Button { Text = "开始扩写", Location = new Point(260, 250), Width = 90, Height = 35, DialogResult = DialogResult.OK };
btnOk.Click += BtnOk_Click;
btnCancel = new Button { Text = "取消", Location = new Point(370, 250), Width = 90, Height = 35, DialogResult = DialogResult.Cancel };
// Add Controls
this.Controls.Add(lblTemplate);
this.Controls.Add(cmbTemplates);
this.Controls.Add(lblCustom);
this.Controls.Add(txtCustomPrompt);
this.Controls.Add(btnOk);
this.Controls.Add(btnCancel);
this.AcceptButton = btnOk;
this.CancelButton = btnCancel;
}
private void InitializeTemplates()
{
foreach (var key in _templates.Keys)
{
cmbTemplates.Items.Add(key);
}
if (cmbTemplates.Items.Count > 0)
{
cmbTemplates.SelectedIndex = 0;
}
}
private void CmbTemplates_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbTemplates.SelectedItem != null && _templates.ContainsKey(cmbTemplates.SelectedItem.ToString()))
{
txtCustomPrompt.Text = _templates[cmbTemplates.SelectedItem.ToString()];
}
}
private void BtnOk_Click(object sender, EventArgs e)
{
SelectedPrompt = txtCustomPrompt.Text.Trim();
if (string.IsNullOrEmpty(SelectedPrompt))
{
MessageBox.Show("扩写要求不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
this.DialogResult = DialogResult.None; // Prevent closing
return;
}
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using WordAddIn.Properties;
namespace WordAddIn
{
public class FormatOptionsForm : Form
{
public string SelectedFontName { get; private set; }
public float SelectedFontSize { get; private set; }
public float SelectedLineSpacing { get; private set; }
private ComboBox cmbFontName;
private ComboBox cmbFontSize;
private ComboBox cmbLineSpacing;
private Button btnOk;
private Button btnCancel;
public FormatOptionsForm()
{
InitializeComponent();
LoadSettings();
}
private void InitializeComponent()
{
this.Text = "格式化设置";
this.Size = new Size(350, 250);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
int labelX = 30;
int inputX = 120;
int startY = 30;
int gapY = 40;
// 1. 字体
var lblFont = new Label { Text = "字体:", Location = new Point(labelX, startY + 5), AutoSize = true };
cmbFontName = new ComboBox { Location = new Point(inputX, startY), Width = 150, DropDownStyle = ComboBoxStyle.DropDownList };
// 简单添加几个常用中文字体
cmbFontName.Items.AddRange(new object[] { "微软雅黑", "宋体", "黑体", "楷体", "Arial", "Times New Roman" });
// 2. 字号
var lblSize = new Label { Text = "字号:", Location = new Point(labelX, startY + gapY + 5), AutoSize = true };
cmbFontSize = new ComboBox { Location = new Point(inputX, startY + gapY), Width = 150, DropDownStyle = ComboBoxStyle.DropDownList };
cmbFontSize.Items.AddRange(new object[] { "9", "10", "10.5", "11", "12", "14", "16", "18", "22", "24" });
// 3. 行间距
var lblSpacing = new Label { Text = "行间距(倍):", Location = new Point(labelX, startY + gapY * 2 + 5), AutoSize = true };
cmbLineSpacing = new ComboBox { Location = new Point(inputX, startY + gapY * 2), Width = 150, DropDownStyle = ComboBoxStyle.DropDownList };
cmbLineSpacing.Items.AddRange(new object[] { "1.0", "1.25", "1.5", "2.0", "2.5", "3.0" });
// Buttons
btnOk = new Button { Text = "确定", Location = new Point(130, 160), Width = 80, Height = 30, DialogResult = DialogResult.OK };
btnOk.Click += BtnOk_Click;
btnCancel = new Button { Text = "取消", Location = new Point(220, 160), Width = 80, Height = 30, DialogResult = DialogResult.Cancel };
this.Controls.Add(lblFont);
this.Controls.Add(cmbFontName);
this.Controls.Add(lblSize);
this.Controls.Add(cmbFontSize);
this.Controls.Add(lblSpacing);
this.Controls.Add(cmbLineSpacing);
this.Controls.Add(btnOk);
this.Controls.Add(btnCancel);
this.AcceptButton = btnOk;
this.CancelButton = btnCancel;
}
private void LoadSettings()
{
// 读取保存的设置,如果没有则使用默认值
string fontName = Settings.Default.FormatFontName;
float fontSize = Settings.Default.FormatFontSize;
float lineSpacing = Settings.Default.FormatLineSpacing;
if (cmbFontName.Items.Contains(fontName))
cmbFontName.SelectedItem = fontName;
else
cmbFontName.SelectedIndex = 0;
string sizeStr = fontSize.ToString();
if (cmbFontSize.Items.Contains(sizeStr))
cmbFontSize.SelectedItem = sizeStr;
else
cmbFontSize.SelectedItem = "12";
string spacingStr = lineSpacing.ToString();
if (cmbLineSpacing.Items.Contains(spacingStr))
cmbLineSpacing.SelectedItem = spacingStr;
else
cmbLineSpacing.SelectedItem = "1.5";
}
private void BtnOk_Click(object sender, EventArgs e)
{
// 保存设置
if (cmbFontName.SelectedItem != null)
Settings.Default.FormatFontName = cmbFontName.SelectedItem.ToString();
if (cmbFontSize.SelectedItem != null && float.TryParse(cmbFontSize.SelectedItem.ToString(), out float size))
Settings.Default.FormatFontSize = size;
if (cmbLineSpacing.SelectedItem != null && float.TryParse(cmbLineSpacing.SelectedItem.ToString(), out float spacing))
Settings.Default.FormatLineSpacing = spacing;
Settings.Default.Save();
// 更新属性供外部调用
SelectedFontName = Settings.Default.FormatFontName;
SelectedFontSize = Settings.Default.FormatFontSize;
SelectedLineSpacing = Settings.Default.FormatLineSpacing;
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using WordAddIn.Properties;
namespace WordAddIn
{
public class ImageOptionsForm : Form
{
public string SelectedStyle { get; private set; }
public string AdditionalPrompt { get; private set; }
private ComboBox cmbStyles;
private TextBox txtAdditionalPrompt;
private Button btnOk;
private Button btnCancel;
private readonly string[] _styles = new string[]
{
"写实摄影 (Photorealistic)",
"软件架构图 (Architecture Diagram)",
"技术原理图 (Technical Schematic)",
"手绘草图 (Sketch)",
"卡通插画 (Cartoon)",
"3D 渲染 (3D Render)",
"水彩画 (Watercolor)",
"赛博朋克 (Cyberpunk)"
};
public ImageOptionsForm()
{
InitializeComponent();
InitializeStyles();
}
private void InitializeComponent()
{
this.Text = "生成配图设置";
this.Size = new Size(450, 300);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
int startY = 30;
int gapY = 60;
int labelX = 30;
int inputX = 30;
int inputWidth = 370;
// 1. 风格选择
var lblStyle = new Label { Text = "图片风格:", Location = new Point(labelX, startY), AutoSize = true };
cmbStyles = new ComboBox { Location = new Point(inputX, startY + 25), Width = inputWidth, DropDownStyle = ComboBoxStyle.DropDownList };
// 2. 补充描述
var lblPrompt = new Label { Text = "补充描述 (可选,例如:背景要白色):", Location = new Point(labelX, startY + gapY + 10), AutoSize = true };
txtAdditionalPrompt = new TextBox { Location = new Point(inputX, startY + gapY + 35), Width = inputWidth, Height = 60, Multiline = true, ScrollBars = ScrollBars.Vertical };
// txtAdditionalPrompt.PlaceholderText = "例如:背景要白色,色调偏蓝...";
// Buttons
btnOk = new Button { Text = "生成图片", Location = new Point(210, 210), Width = 90, Height = 35, DialogResult = DialogResult.OK };
btnOk.Click += BtnOk_Click;
btnCancel = new Button { Text = "取消", Location = new Point(310, 210), Width = 90, Height = 35, DialogResult = DialogResult.Cancel };
this.Controls.Add(lblStyle);
this.Controls.Add(cmbStyles);
this.Controls.Add(lblPrompt);
this.Controls.Add(txtAdditionalPrompt);
this.Controls.Add(btnOk);
this.Controls.Add(btnCancel);
this.AcceptButton = btnOk;
this.CancelButton = btnCancel;
}
private void InitializeStyles()
{
cmbStyles.Items.AddRange(_styles);
// 尝试恢复上次的选择
string lastStyle = Settings.Default.LastImageStyle;
if (!string.IsNullOrEmpty(lastStyle) && cmbStyles.Items.Contains(lastStyle))
{
cmbStyles.SelectedItem = lastStyle;
}
else
{
cmbStyles.SelectedIndex = 0; // 默认选中第一个
}
}
private void BtnOk_Click(object sender, EventArgs e)
{
SelectedStyle = cmbStyles.SelectedItem.ToString();
AdditionalPrompt = txtAdditionalPrompt.Text.Trim();
// 保存选择
Settings.Default.LastImageStyle = SelectedStyle;
Settings.Default.Save();
}
}
}

View File

@@ -0,0 +1,156 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace WordAddIn
{
public class LoadingForm : Form
{
private Label lblMessage;
private Timer animationTimer;
private int _spinnerAngle = 0;
private const int SPINNER_SIZE = 60;
// 现代化配色
private readonly Color _primaryColor = Color.FromArgb(43, 87, 154); // Word Blue
private readonly Color _backgroundColor = Color.White;
private readonly Color _borderColor = Color.FromArgb(100, 100, 100);
private readonly Font _textFont = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
public LoadingForm(string message = "AI 正在思考中...")
{
InitializeComponent(message);
// 开启双缓冲以减少闪烁
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
this.UpdateStyles();
this.Text = "AI助手";
}
private void InitializeComponent(string message)
{
this.SuspendLayout();
// Form settings
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterScreen;
this.Size = new Size(500, 250);
this.BackColor = _backgroundColor;
this.TopMost = true;
this.ShowInTaskbar = false;
// Timer
animationTimer = new Timer();
animationTimer.Interval = 30; // 33fps
animationTimer.Tick += AnimationTimer_Tick;
animationTimer.Start();
// Label
this.lblMessage = new Label();
this.lblMessage.Text = message;
this.lblMessage.AutoSize = false;
this.lblMessage.TextAlign = ContentAlignment.TopCenter;
this.lblMessage.Dock = DockStyle.None;
this.lblMessage.Width = this.Width;
this.lblMessage.Height = 40;
this.lblMessage.Location = new Point(0, 160); // 放在 Spinner 下方
this.lblMessage.Font = _textFont;
this.lblMessage.ForeColor = Color.FromArgb(64, 64, 64);
this.lblMessage.BackColor = Color.Transparent; // 背景透明,防止遮挡边框
this.Controls.Add(this.lblMessage);
this.ResumeLayout(false);
}
private void AnimationTimer_Tick(object sender, EventArgs e)
{
_spinnerAngle = (_spinnerAngle + 10) % 360;
this.Invalidate(); // 触发重绘
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
// 1. 绘制边框
using (Pen borderPen = new Pen(_borderColor, 2))
{
g.DrawRectangle(borderPen, 0, 0, this.Width - 1, this.Height - 1);
}
// 2. 绘制 Spinner (中心位置)
int centerX = this.Width / 2;
int centerY = 100; // 居中
g.TranslateTransform(centerX, centerY);
g.RotateTransform(_spinnerAngle);
// 绘制一个渐变的圆环或一串圆点
// 这里我们画 8 个圆点,透明度渐变
int dotCount = 10;
int radius = SPINNER_SIZE / 2;
int dotSize = 6;
for (int i = 0; i < dotCount; i++)
{
// 计算每个点的透明度 (0-255)
// 使得看起来像是有拖尾
int alpha = 255 * (i + 1) / dotCount;
using (Brush brush = new SolidBrush(Color.FromArgb(alpha, _primaryColor)))
{
// 保存当前状态
var state = g.Save();
// 旋转到对应角度
float angle = 360f / dotCount * i;
g.RotateTransform(angle);
// 在半径处画圆点
g.FillEllipse(brush, radius - dotSize, -dotSize / 2, dotSize, dotSize);
// 恢复状态
g.Restore(state);
}
}
g.ResetTransform();
}
// 允许在非 UI 线程关闭窗体
public void CloseSafe()
{
if (this.IsDisposed) return;
if (this.InvokeRequired)
{
this.Invoke(new Action(CloseSafe));
}
else
{
animationTimer.Stop();
this.Close();
}
}
// 允许拖动窗体
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool ReleaseCapture();
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WordAddIn
{
public class LoginForm : Form
{
private TextBox txtUsername;
private TextBox txtPassword;
private Button btnLogin;
private Button btnCancel;
public LoginForm()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.Text = "AI助手 - 用户登录";
this.Size = new Size(500, 320); // 增大尺寸
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.BackColor = Color.White;
// 调整布局参数
int startY = 80;
int gapY = 60;
int labelX = 80;
int inputX = 160;
int inputWidth = 220;
// 标题区域
Label lblTitle = new Label
{
Text = "AI助手",
Font = new Font("微软雅黑", 16, FontStyle.Bold),
Location = new Point(0, 25),
AutoSize = false,
Width = 500,
Height = 40,
TextAlign = ContentAlignment.MiddleCenter,
ForeColor = Color.FromArgb(43, 87, 154)
};
this.Controls.Add(lblTitle);
// 1. 用户名
var lblUser = new Label { Text = "用户名:", Location = new Point(labelX, startY + 5), AutoSize = true, Font = new Font("微软雅黑", 11) };
txtUsername = new TextBox { Location = new Point(inputX, startY), Width = inputWidth, Font = new Font("微软雅黑", 11), Text = "huanghai" };
// 2. 密码
var lblPass = new Label { Text = "密 码:", Location = new Point(labelX, startY + gapY + 5), AutoSize = true, Font = new Font("微软雅黑", 11) };
txtPassword = new TextBox { Location = new Point(inputX, startY + gapY), Width = inputWidth, Font = new Font("微软雅黑", 11), PasswordChar = '●', Text = "12345678" };
// Buttons
btnLogin = new Button
{
Text = "立即登录",
Location = new Point(110, 220),
Width = 120,
Height = 40,
BackColor = Color.FromArgb(43, 87, 154),
ForeColor = Color.White,
FlatStyle = FlatStyle.Flat,
DialogResult = DialogResult.None,
Font = new Font("微软雅黑", 10, FontStyle.Bold),
Cursor = Cursors.Hand
};
btnLogin.FlatAppearance.BorderSize = 0;
btnLogin.Click += BtnLogin_Click;
btnCancel = new Button
{
Text = "取消",
Location = new Point(250, 220),
Width = 120,
Height = 40,
DialogResult = DialogResult.Cancel,
Font = new Font("微软雅黑", 10),
Cursor = Cursors.Hand
};
this.Controls.Add(lblUser);
this.Controls.Add(txtUsername);
this.Controls.Add(lblPass);
this.Controls.Add(txtPassword);
this.Controls.Add(btnLogin);
this.Controls.Add(btnCancel);
this.AcceptButton = btnLogin;
this.CancelButton = btnCancel;
}
private void BtnLogin_Click(object sender, EventArgs e)
{
string user = txtUsername.Text.Trim();
string pass = txtPassword.Text.Trim();
// 模拟验证逻辑
if (user == "huanghai" && pass == "12345678")
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show("用户名或密码错误!\n(默认账号: huanghai, 密码: 12345678)", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtPassword.Focus();
txtPassword.SelectAll();
}
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
namespace WordAddIn.Models
{
// Chat Completion Models
public class ChatCompletionRequest
{
public string model { get; set; } = "gpt-3.5-turbo";
public List<Message> messages { get; set; }
public double temperature { get; set; } = 0.7;
}
public class Message
{
public string role { get; set; }
public string content { get; set; }
}
public class ChatCompletionResponse
{
public string id { get; set; }
public List<Choice> choices { get; set; }
}
public class Choice
{
public Message message { get; set; }
}
// Image Generation Models
public class ImageGenerationRequest
{
public string model { get; set; } = "dall-e-3";
public string prompt { get; set; }
public int n { get; set; } = 1;
public string size { get; set; } = "1024x1024";
}
public class ImageGenerationResponse
{
public List<ImageItem> data { get; set; }
}
public class ImageItem
{
public string url { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("WordAddIn")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WordAddIn")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("9113a477-5db3-40e1-bcb5-536bba10d35d")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WordAddIn.Properties {
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WordAddIn.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,74 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WordAddIn.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("微软雅黑")]
public string FormatFontName {
get {
return ((string)(this["FormatFontName"]));
}
set {
this["FormatFontName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("12")]
public float FormatFontSize {
get {
return ((float)(this["FormatFontSize"]));
}
set {
this["FormatFontSize"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1.5")]
public float FormatLineSpacing {
get {
return ((float)(this["FormatLineSpacing"]));
}
set {
this["FormatLineSpacing"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("写实摄影 (Photorealistic)")]
public string LastImageStyle {
get {
return ((string)(this["LastImageStyle"]));
}
set {
this["LastImageStyle"] = value;
}
}
}
}

View File

@@ -0,0 +1,20 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="WordAddIn.Properties" GeneratedClassName="Settings">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings>
<Setting Name="FormatFontName" Type="System.String" Scope="User">
<Value Profile="(Default)">微软雅黑</Value>
</Setting>
<Setting Name="FormatFontSize" Type="System.Single" Scope="User">
<Value Profile="(Default)">12</Value>
</Setting>
<Setting Name="FormatLineSpacing" Type="System.Single" Scope="User">
<Value Profile="(Default)">1.5</Value>
</Setting>
<Setting Name="LastImageStyle" Type="System.String" Scope="User">
<Value Profile="(Default)">写实摄影 (Photorealistic)</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -0,0 +1,213 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
namespace WordAddIn
{
public class ReferenceGeneratorForm : Form
{
private TabControl tabControl;
private TabPage tabText;
private TabPage tabFile;
private RichTextBox txtReferenceInput;
private TextBox txtFilePath;
private Button btnBrowse;
private NumericUpDown numWordCount;
private Button btnGenerate;
private Button btnCancel;
public string ReferenceContent { get; private set; }
public int WordLimit { get; private set; }
public bool IsFileMode { get; private set; }
public string SelectedFilePath { get; private set; }
public ReferenceGeneratorForm()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.Text = "素材写作 - AI助手";
this.Size = new Size(650, 520); // 增大尺寸
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.BackColor = Color.White;
// 1. 选项卡控件
tabControl = new TabControl
{
Location = new Point(25, 25),
Size = new Size(585, 300), // 增大尺寸
Font = new Font("微软雅黑", 11) // 增大字体
};
// Tab 1: 文本输入
tabText = new TabPage("直接输入");
tabText.BackColor = Color.White;
tabText.Padding = new Padding(10);
txtReferenceInput = new RichTextBox
{
Dock = DockStyle.Fill,
BorderStyle = BorderStyle.None,
Font = new Font("微软雅黑", 11),
BackColor = Color.WhiteSmoke,
Text = ""
};
tabText.Controls.Add(txtReferenceInput);
// Tab 2: 文件上传
tabFile = new TabPage("上传文档");
tabFile.BackColor = Color.White;
Label lblFileTip = new Label
{
Text = "请选择参考文档 (支持 Word/Txt):",
Location = new Point(30, 60),
AutoSize = true,
Font = new Font("微软雅黑", 12)
};
txtFilePath = new TextBox
{
Location = new Point(30, 100),
Width = 400, // 变宽
Height = 30,
ReadOnly = true,
Font = new Font("微软雅黑", 11)
};
btnBrowse = new Button
{
Text = "浏览...",
Location = new Point(440, 98),
Width = 100, // 变大
Height = 35,
Font = new Font("微软雅黑", 10),
Cursor = Cursors.Hand
};
btnBrowse.Click += BtnBrowse_Click;
tabFile.Controls.Add(lblFileTip);
tabFile.Controls.Add(txtFilePath);
tabFile.Controls.Add(btnBrowse);
tabControl.Controls.Add(tabFile);
tabControl.Controls.Add(tabText);
// 2. 字数限制区域 (显著优化)
int settingsY = 350;
Label lblWordCount = new Label
{
Text = "生成字数上限:",
Location = new Point(30, settingsY + 5),
AutoSize = true,
Font = new Font("微软雅黑", 12, FontStyle.Bold) // 加粗加大
};
// 分开初始化以确保顺序和值正确
numWordCount = new NumericUpDown();
numWordCount.Location = new Point(200, settingsY); // 移到 200,避开标签
numWordCount.Width = 120;
numWordCount.Font = new Font("微软雅黑", 14);
numWordCount.Minimum = 0; // 先重置范围
numWordCount.Maximum = 10000;
numWordCount.Minimum = 100;
numWordCount.Increment = 100;
numWordCount.Value = 500; // 显式最后设置
Label lblWordUnit = new Label
{
Text = "字",
Location = new Point(330, settingsY + 5), // 跟着移动
AutoSize = true,
Font = new Font("微软雅黑", 12)
};
// 3. 底部按钮
btnGenerate = new Button
{
Text = "开始生成",
Location = new Point(160, 410),
Width = 140,
Height = 45,
BackColor = Color.FromArgb(43, 87, 154),
ForeColor = Color.White,
FlatStyle = FlatStyle.Flat,
DialogResult = DialogResult.OK,
Font = new Font("微软雅黑", 12, FontStyle.Bold),
Cursor = Cursors.Hand
};
btnGenerate.FlatAppearance.BorderSize = 0;
btnGenerate.Click += BtnGenerate_Click;
btnCancel = new Button
{
Text = "取消",
Location = new Point(320, 410),
Width = 140,
Height = 45,
DialogResult = DialogResult.Cancel,
Font = new Font("微软雅黑", 12),
Cursor = Cursors.Hand
};
this.Controls.Add(tabControl);
this.Controls.Add(lblWordCount);
this.Controls.Add(numWordCount);
this.Controls.Add(lblWordUnit);
this.Controls.Add(btnGenerate);
this.Controls.Add(btnCancel);
this.AcceptButton = btnGenerate;
this.CancelButton = btnCancel;
}
private void BtnBrowse_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "Word 文档 (*.docx;*.doc)|*.docx;*.doc|文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*";
ofd.Title = "选择参考文档";
if (ofd.ShowDialog() == DialogResult.OK)
{
txtFilePath.Text = ofd.FileName;
}
}
}
private void BtnGenerate_Click(object sender, EventArgs e)
{
WordLimit = (int)numWordCount.Value;
if (tabControl.SelectedTab == tabFile)
{
if (string.IsNullOrWhiteSpace(txtFilePath.Text) || !File.Exists(txtFilePath.Text))
{
MessageBox.Show("请选择有效的参考文档。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
IsFileMode = true;
SelectedFilePath = txtFilePath.Text;
ReferenceContent = null; // 由调用方读取
}
else
{
string text = txtReferenceInput.Text.Trim();
if (string.IsNullOrWhiteSpace(text))
{
MessageBox.Show("请输入参考文本内容。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
IsFileMode = false;
ReferenceContent = text;
}
this.DialogResult = DialogResult.OK;
this.Close();
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office.Interop.Word;
namespace WordAddIn
{
public class StyleProfile
{
public Dictionary<string, StyleAttributes> Styles { get; set; } = new Dictionary<string, StyleAttributes>();
public string NumberingSchemeDescription { get; set; } // 描述编号规则,如 "一级标题使用一、,二级使用(一)"
}
public class StyleAttributes
{
public string FontName { get; set; } // ASCII Font
public string FontNameFarEast { get; set; } // Asian Font
public float FontSize { get; set; }
public int Color { get; set; }
public int Bold { get; set; }
public float LineSpacing { get; set; }
public Word.WdLineSpacing LineSpacingRule { get; set; }
public float FirstLineIndent { get; set; }
public float SpaceBefore { get; set; }
public float SpaceAfter { get; set; }
public string StyleName { get; set; } // Word内部的样式名称
}
public static class StyleAnalyzer
{
public static StyleProfile AnalyzeDocumentStyles(Document doc)
{
var profile = new StyleProfile();
// 定义我们需要关注的样式层级
// wdStyleHeading1 = -2, Heading2 = -3, Heading3 = -4, Normal = -1
var targets = new Dictionary<WdBuiltinStyle, string>
{
{ WdBuiltinStyle.wdStyleHeading1, "Heading 1" },
{ WdBuiltinStyle.wdStyleHeading2, "Heading 2" },
{ WdBuiltinStyle.wdStyleHeading3, "Heading 3" },
{ WdBuiltinStyle.wdStyleNormal, "Normal" }
};
foreach (var target in targets)
{
try
{
// 获取文档中的样式定义
Style style = doc.Styles[target.Key];
var attrs = new StyleAttributes
{
FontName = style.Font.Name,
FontNameFarEast = style.Font.NameFarEast,
FontSize = style.Font.Size,
Color = (int)style.Font.Color,
Bold = style.Font.Bold,
StyleName = style.NameLocal, // 获取本地化名称,如 "标题 1"
LineSpacing = style.ParagraphFormat.LineSpacing,
LineSpacingRule = style.ParagraphFormat.LineSpacingRule,
FirstLineIndent = style.ParagraphFormat.CharacterUnitFirstLineIndent > 0 ? style.ParagraphFormat.CharacterUnitFirstLineIndent : style.ParagraphFormat.FirstLineIndent,
SpaceBefore = style.ParagraphFormat.SpaceBefore,
SpaceAfter = style.ParagraphFormat.SpaceAfter
};
profile.Styles[target.Value] = attrs;
}
catch
{
// 样式可能不存在
}
}
return profile;
}
public static string GenerateStyleDescription(StyleProfile profile)
{
var sb = new StringBuilder();
sb.AppendLine("文档排版规则:");
foreach (var kv in profile.Styles)
{
var s = kv.Value;
string levelName = kv.Key == "Normal" ? "正文" : kv.Key.Replace("Heading ", "级标题");
sb.AppendLine($"- {levelName}: 中文字体[{s.FontNameFarEast}], 英文字体[{s.FontName}], 大小[{s.FontSize}]");
}
return sb.ToString();
}
}
}

237
WordAddIn/WordAddIn/ThisAddIn.Designer.cs generated Normal file
View File

@@ -0,0 +1,237 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#pragma warning disable 414
namespace WordAddIn {
///
[Microsoft.VisualStudio.Tools.Applications.Runtime.StartupObjectAttribute(0)]
[global::System.Security.Permissions.PermissionSetAttribute(global::System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public sealed partial class ThisAddIn : Microsoft.Office.Tools.AddInBase {
internal Microsoft.Office.Tools.CustomTaskPaneCollection CustomTaskPanes;
internal Microsoft.Office.Tools.SmartTagCollection VstoSmartTags;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
private global::System.Object missing = global::System.Type.Missing;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
internal Microsoft.Office.Interop.Word.Application Application;
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
public ThisAddIn(global::Microsoft.Office.Tools.Word.ApplicationFactory factory, global::System.IServiceProvider serviceProvider) :
base(factory, serviceProvider, "AddIn", "ThisAddIn") {
Globals.Factory = factory;
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void Initialize() {
base.Initialize();
this.Application = this.GetHostItem<Microsoft.Office.Interop.Word.Application>(typeof(Microsoft.Office.Interop.Word.Application), "Application");
Globals.ThisAddIn = this;
global::System.Windows.Forms.Application.EnableVisualStyles();
this.InitializeCachedData();
this.InitializeControls();
this.InitializeComponents();
this.InitializeData();
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void FinishInitialization() {
this.InternalStartup();
this.OnStartup();
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void InitializeDataBindings() {
this.BeginInitialization();
this.BindToData();
this.EndInitialization();
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeCachedData() {
if ((this.DataHost == null)) {
return;
}
if (this.DataHost.IsCacheInitialized) {
this.DataHost.FillCachedData(this);
}
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeData() {
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void BindToData() {
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private void StartCaching(string MemberName) {
this.DataHost.StartCaching(this, MemberName);
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private void StopCaching(string MemberName) {
this.DataHost.StopCaching(this, MemberName);
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private bool IsCached(string MemberName) {
return this.DataHost.IsCached(this, MemberName);
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void BeginInitialization() {
this.BeginInit();
this.CustomTaskPanes.BeginInit();
this.VstoSmartTags.BeginInit();
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void EndInitialization() {
this.VstoSmartTags.EndInit();
this.CustomTaskPanes.EndInit();
this.EndInit();
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeControls() {
this.CustomTaskPanes = Globals.Factory.CreateCustomTaskPaneCollection(null, null, "CustomTaskPanes", "CustomTaskPanes", this);
this.VstoSmartTags = Globals.Factory.CreateSmartTagCollection(null, null, "VstoSmartTags", "VstoSmartTags", this);
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeComponents() {
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private bool NeedsFill(string MemberName) {
return this.DataHost.NeedsFill(this, MemberName);
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void OnShutdown() {
this.VstoSmartTags.Dispose();
this.CustomTaskPanes.Dispose();
base.OnShutdown();
}
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
internal sealed partial class Globals {
///
private Globals() {
}
private static ThisAddIn _ThisAddIn;
private static global::Microsoft.Office.Tools.Word.ApplicationFactory _factory;
private static ThisRibbonCollection _ThisRibbonCollection;
internal static ThisAddIn ThisAddIn {
get {
return _ThisAddIn;
}
set {
if ((_ThisAddIn == null)) {
_ThisAddIn = value;
}
else {
throw new System.NotSupportedException();
}
}
}
internal static global::Microsoft.Office.Tools.Word.ApplicationFactory Factory {
get {
return _factory;
}
set {
if ((_factory == null)) {
_factory = value;
}
else {
throw new System.NotSupportedException();
}
}
}
internal static ThisRibbonCollection Ribbons {
get {
if ((_ThisRibbonCollection == null)) {
_ThisRibbonCollection = new ThisRibbonCollection(_factory.GetRibbonFactory());
}
return _ThisRibbonCollection;
}
}
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
internal sealed partial class ThisRibbonCollection : Microsoft.Office.Tools.Ribbon.RibbonCollectionBase {
///
internal ThisRibbonCollection(global::Microsoft.Office.Tools.Ribbon.RibbonFactory factory) :
base(factory) {
}
}
}

View File

@@ -0,0 +1,5 @@
<hostitem:hostItem hostitem:baseType="Microsoft.Office.Tools.AddInBase" hostitem:namespace="WordAddIn" hostitem:className="ThisAddIn" hostitem:identifier="ThisAddIn" hostitem:primaryCookie="AddIn" hostitem:master="true" hostitem:factoryType="Microsoft.Office.Tools.Word.ApplicationFactory" hostitem:startupIndex="0" xmlns:hostitem="http://schemas.microsoft.com/2004/VisualStudio/Tools/Applications/HostItem.xsd">
<hostitem:hostObject hostitem:name="Application" hostitem:identifier="Application" hostitem:type="Microsoft.Office.Interop.Word.Application" hostitem:cookie="Application" hostitem:modifier="Internal" />
<hostitem:hostControl hostitem:name="CustomTaskPanes" hostitem:identifier="CustomTaskPanes" hostitem:type="Microsoft.Office.Tools.CustomTaskPaneCollection" hostitem:primaryCookie="CustomTaskPanes" hostitem:modifier="Internal" />
<hostitem:hostControl hostitem:name="VstoSmartTags" hostitem:identifier="VstoSmartTags" hostitem:type="Microsoft.Office.Tools.SmartTagCollection" hostitem:primaryCookie="VstoSmartTags" hostitem:modifier="Internal" />
</hostitem:hostItem>

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
namespace WordAddIn
{
public partial class ThisAddIn
{
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new AiRibbon();
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
#region VSTO 生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
}

View File

@@ -0,0 +1,285 @@
<Project ToolsVersion="17.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<!--
This section defines project-level properties.
AssemblyName
Name of the output assembly.
Configuration
Specifies a default value for debug.
OutputType
Must be "Library" for VSTO.
Platform
Specifies what CPU the output of this project can run on.
NoStandardLibraries
Set to "false" for VSTO.
RootNamespace
In C#, this specifies the namespace given to new files. In VB, all objects are
wrapped in this namespace at runtime.
-->
<PropertyGroup>
<ProjectTypeGuids>{BAA0C2D2-18E2-41B9-852F-F413020CAA33};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EC0A80FA-FCBD-4239-945A-627B20CCCBAA}</ProjectGuid>
<OutputType>Library</OutputType>
<NoStandardLibraries>false</NoStandardLibraries>
<RootNamespace>WordAddIn</RootNamespace>
<AssemblyName>WordAddIn</AssemblyName>
<LoadBehavior>3</LoadBehavior>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<DefineConstants>VSTO40;UseOfficeInterop</DefineConstants>
<BootstrapperEnabled>true</BootstrapperEnabled>
<BootstrapperComponentsLocation>HomeSite</BootstrapperComponentsLocation>
<ResolveComReferenceSilent>true</ResolveComReferenceSilent>
</PropertyGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.VSTORuntime.4.0">
<Visible>False</Visible>
<ProductName>Microsoft Visual Studio 2010 Tools for Office Runtime %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<PropertyGroup>
<!--
OfficeApplication
Add-in host application
-->
<OfficeApplication>Word</OfficeApplication>
</PropertyGroup>
<!--
This section defines properties that are set when the "Debug" configuration is selected.
DebugSymbols
If "true", create symbols (.pdb). If "false", do not create symbols.
DefineConstants
Constants defined for the preprocessor.
EnableUnmanagedDebugging
If "true", starting the debugger will attach both managed and unmanaged debuggers.
Optimize
If "true", optimize the build output. If "false", do not optimize.
OutputPath
Output path of project relative to the project file.
WarningLevel
Warning level for the compiler.
-->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
<DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
<WarningLevel>4</WarningLevel>
<StartAction>Program</StartAction>
<StartProgram>C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE</StartProgram>
</PropertyGroup>
<!--
This section defines properties that are set when the "Release" configuration is selected.
DebugSymbols
If "true", create symbols (.pdb). If "false", do not create symbols.
DefineConstants
Constants defined for the preprocessor.
EnableUnmanagedDebugging
If "true", starting the debugger will attach both managed and unmanaged debuggers.
Optimize
If "true", optimize the build output. If "false", do not optimize.
OutputPath
Output path of project relative to the project file.
WarningLevel
Warning level for the compiler.
-->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
<WarningLevel>4</WarningLevel>
<StartAction>Program</StartAction>
<StartProgram>C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE</StartProgram>
</PropertyGroup>
<!--
This section specifies references for the project.
-->
<ItemGroup>
<Reference Include="Accessibility" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Tools.v4.0.Framework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Tools.Applications.Runtime, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Tools, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Tools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Tools.Word, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Tools.Common.v4.0.Utilities, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>True</Private>
</Reference>
</ItemGroup>
<Choose>
<When Condition="$([System.String]::Copy(&quot;;$(DefineConstants);&quot;).ToLower().Contains(';useofficeinterop;')) or $([System.String]::Copy(&quot;,$(DefineConstants),&quot;).ToLower().Contains(',useofficeinterop,'))">
<ItemGroup>
<Reference Include="Office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<COMReference Include="Microsoft.Office.Core">
<Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
<VersionMajor>2</VersionMajor>
<VersionMinor>7</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
<COMReference Include="Microsoft.Office.Interop.Word">
<Guid>{00020905-0000-0000-C000-000000000046}</Guid>
<VersionMajor>8</VersionMajor>
<VersionMinor>6</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Reference Include="stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>False</Private>
</Reference>
</ItemGroup>
<!--
This section defines the user source files that are part of the project.
A "Compile" element specifies a source file to compile.
An "EmbeddedResource" element specifies an .resx file for embedded resources.
A "None" element specifies a file that is not to be passed to the compiler (for instance,
a text file or XML file).
The "AppDesigner" element specifies the directory where the application properties files
can be found.
-->
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="ThisAddIn.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="AiRibbon.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Models.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="ExpandOptionsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormatOptionsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ImageOptionsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ReferenceGeneratorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StyleAnalyzer.cs" />
<Compile Include="LoginForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="LoadingForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AiService.cs">
<SubType>Code</SubType>
</Compile>
<EmbeddedResource Include="AiRibbon.xml" />
<None Include="ThisAddIn.Designer.xml">
<DependentUpon>ThisAddIn.cs</DependentUpon>
</None>
<Compile Include="ThisAddIn.Designer.cs">
<DependentUpon>ThisAddIn.Designer.xml</DependentUpon>
</Compile>
<AppDesigner Include="Properties\" />
<None Include="WordAddIn_TemporaryKey.pfx" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>WordAddIn_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>1B8D8AB21D9D321D59A4C13B926DAB7BD3677944</ManifestCertificateThumbprint>
</PropertyGroup>
<!-- Include the build rules for a C# project. -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- Include additional build rules for an Office application add-in. -->
<Import Project="$(VSToolsPath)\OfficeTools\Microsoft.VisualStudio.Tools.Office.targets" Condition="'$(VSToolsPath)' != ''" />
<!-- This section defines VSTO properties that describe the host-changeable project properties. -->
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}">
<ProjectProperties HostName="Word" HostPackage="{29A7B9D7-A7F1-4328-8EF0-6B2D1A56B2C1}" OfficeVersion="15.0" VstxVersion="4.0" ApplicationType="Word" Language="cs" TemplatesPath="" DebugInfoExeName="#Software\Microsoft\Office\16.0\Word\InstallRoot\Path#WINWORD.EXE" DebugInfoCommandLine="/x" AddItemTemplatesGuid="{51063C3A-E220-4D12-8922-BDA915ACD783}" />
<Host Name="Word" GeneratedCodeNamespace="WordAddIn" IconIndex="0">
<HostItem Name="ThisAddIn" Code="ThisAddIn.cs" CanonicalName="AddIn" CanActivate="false" IconIndex="1" Blueprint="ThisAddIn.Designer.xml" GeneratedCode="ThisAddIn.Designer.cs" />
</Host>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,203 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<asmv1:assemblyIdentity name="WordAddIn.dll" version="1.0.0.0" publicKeyToken="06a92c46db516926" language="neutral" processorArchitecture="msil" type="win32" />
<description xmlns="urn:schemas-microsoft-com:asm.v1">WordAddIn</description>
<application />
<entryPoint>
<co.v1:customHostSpecified />
</entryPoint>
<trustInfo>
<security>
<applicationRequestMinimum>
<PermissionSet Unrestricted="true" ID="Custom" SameSite="site" />
<defaultAssemblyRequest permissionSetReference="Custom" />
</applicationRequestMinimum>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!--
UAC 清单选项
如果要更改 Windows 用户帐户控制级别,请用以下节点之一替换
requestedExecutionLevel 节点。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
如果要利用文件和注册表虚拟化提供
向后兼容性,请删除 requestedExecutionLevel 节点。
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentOS>
<osVersionInfo>
<os majorVersion="5" minorVersion="1" buildNumber="2600" servicePackMajor="0" />
</osVersionInfo>
</dependentOS>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="4.0.30319.0" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Accessibility" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.CSharp" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.Office.Tools" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.Office.Tools.Common" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.Office.Tools.v4.0.Framework" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.Office.Tools.Word" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.VisualStudio.Tools.Applications.Runtime" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="mscorlib" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="stdole" version="7.0.3300.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Core" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Data" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Data.DataSetExtensions" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Drawing" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Net.Http" version="4.2.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Numerics" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Runtime.Serialization" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Windows.Forms" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Xml" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="System.Xml.Linq" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Office.Tools.Common.v4.0.Utilities.dll" size="32664">
<assemblyIdentity name="Microsoft.Office.Tools.Common.v4.0.Utilities" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>jLCTF8Mm6bD4PDN+rnzN6q0+ReXaNgPh68kMWgatFwI=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Newtonsoft.Json.dll" size="721320">
<assemblyIdentity name="Newtonsoft.Json" version="13.0.0.0" publicKeyToken="30AD4FE6B2A6AEED" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>8MB68OhNTdTaS9eCO6RTW8BIGzv2I+1Atlm2gUemu3U=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="WordAddIn.dll" size="88576">
<assemblyIdentity name="WordAddIn" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>UfaMRUXaY5UnnT7MdvsYAO8ZpOP8TEHjaBY8tbnu7lA=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<vstav3:addIn xmlns:vstav3="urn:schemas-microsoft-com:vsta.v3">
<vstav3:entryPointsCollection>
<vstav3:entryPoints>
<vstav3:entryPoint class="WordAddIn.ThisAddIn">
<assemblyIdentity name="WordAddIn" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
</vstav3:entryPoint>
</vstav3:entryPoints>
</vstav3:entryPointsCollection>
<vstav3:update enabled="true">
<vstav3:expiration maximumAge="7" unit="days" />
</vstav3:update>
<vstav3:application>
<vstov4:customizations xmlns:vstov4="urn:schemas-microsoft-com:vsto.v4">
<vstov4:customization>
<vstov4:appAddIn application="Word" loadBehavior="3" keyName="WordAddIn">
<vstov4:friendlyName>WordAddIn</vstov4:friendlyName>
<vstov4:description>WordAddIn</vstov4:description>
<vstov4.1:ribbonTypes xmlns:vstov4.1="urn:schemas-microsoft-com:vsto.v4.1" />
</vstov4:appAddIn>
</vstov4:customization>
</vstov4:customizations>
</vstav3:application>
</vstav3:addIn>
<publisherIdentity name="CN=DESKTOP-Q6H7B6L\Administrator" issuerKeyHash="42606c52715d5764c2f9dab5bee6dcd76cc7a67d" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>6ARPRBIXfvsxGG+s7eLh9omVJw9+d6u+WZ1MWHaFv9g=</DigestValue></Reference></SignedInfo><SignatureValue>lc7c7Ko4DjaT7/xRXqxQ2fw75HYlonmqxf5ZPHDZaSM5o+VXQe8ngHzBAnPrqV9OjS/qq2y7A9thSlCOIOK0A5nRaFldm+gbsG2ZAMawVau7zHAnPx+DSgiS09QuENpimg14k9UvSAQIeaQ2IomwDHtT/AcRQDm6nKGIlCIQXmU=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>23ghUI75yy8GcLhPT5yA+v2ssRfSW+chNqMI+pq5OAr7RXQJOt/+bHdoT9NoS9GQkvblc7ekoUNShIcN601ZZOPgAxkXaQS+La14Wp8GOwnM1qHNJwgla4VAIYjmCj3CUMXLsxspOFVZKRnB6/idYku4Gzhc7NjRBAwe8qWBXaE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="d8bf8576584c9d59beab777e0f279589f6e1e2edac6f1831fb7e1712444f04e8" Description="" Url=""><as:assemblyIdentity name="WordAddIn.dll" version="1.0.0.0" publicKeyToken="06a92c46db516926" language="neutral" processorArchitecture="msil" type="win32" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=DESKTOP-Q6H7B6L\Administrator</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>v/TLe11MKFnBs0fYGMUK+rtaLVC8eIbxj2MA2r2imss=</DigestValue></Reference></SignedInfo><SignatureValue>Ow7xC42PXmaP6HJGnBlAJsrYoDDPA0pe5Kcj/G9EKx98/3iQtnC+sjo16MHcnrR96ksGJm6HGft41fthoalccDcd770dKF9lc6L0KqOVur5/Jyze2Dvw/bmObKCcDPzhxtciK+8XMtNxiN4YxQA0MQMtUGhcpY2XKAWyQIYenIs=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>23ghUI75yy8GcLhPT5yA+v2ssRfSW+chNqMI+pq5OAr7RXQJOt/+bHdoT9NoS9GQkvblc7ekoUNShIcN601ZZOPgAxkXaQS+La14Wp8GOwnM1qHNJwgla4VAIYjmCj3CUMXLsxspOFVZKRnB6/idYku4Gzhc7NjRBAwe8qWBXaE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIICDTCCAXagAwIBAgIQJpSlsxfGbpRNgyjD5Q/yDjANBgkqhkiG9w0BAQsFADBFMUMwQQYDVQQDHjoARABFAFMASwBUAE8AUAAtAFEANgBIADcAQgA2AEwAXABBAGQAbQBpAG4AaQBzAHQAcgBhAHQAbwByMB4XDTI2MDEyNDAwMzYxNVoXDTI3MDEyNDA2MzYxNVowRTFDMEEGA1UEAx46AEQARQBTAEsAVABPAFAALQBRADYASAA3AEIANgBMAFwAQQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA23ghUI75yy8GcLhPT5yA+v2ssRfSW+chNqMI+pq5OAr7RXQJOt/+bHdoT9NoS9GQkvblc7ekoUNShIcN601ZZOPgAxkXaQS+La14Wp8GOwnM1qHNJwgla4VAIYjmCj3CUMXLsxspOFVZKRnB6/idYku4Gzhc7NjRBAwe8qWBXaECAwEAATANBgkqhkiG9w0BAQsFAAOBgQC3GjWMhEFFrn9PGYrQVGNAaibG1sR/eRX3ZWNRjYLhiqbsdeHvm4CX/W0EWd9yZlbaej87XyeUbX+mC3q3yMFVPCRn/W65WYyBPbWTWmSfU9VLKKULAH6WqjS7CqEU3cQSuKcU6nYG4AJu2/FkQJaA82tr3pvcQD28HmOlDeNh0Q==</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>

Binary file not shown.

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<assemblyIdentity name="WordAddIn.vsto" version="1.0.0.0" publicKeyToken="06a92c46db516926" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
<description asmv2:publisher="WordAddIn" asmv2:product="WordAddIn" xmlns="urn:schemas-microsoft-com:asm.v1" />
<deployment install="false" />
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
<framework targetVersion="4.7.2" profile="Full" supportedRuntime="4.0.30319" />
</compatibleFrameworks>
<dependency>
<dependentAssembly dependencyType="install" codebase="WordAddIn.dll.manifest" size="14626">
<assemblyIdentity name="WordAddIn.dll" version="1.0.0.0" publicKeyToken="06a92c46db516926" language="neutral" processorArchitecture="msil" type="win32" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>Cy7n1QaBs9zvjHlZNLpWQeHMimrr7CoRNpQ6mYSMmgw=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<publisherIdentity name="CN=DESKTOP-Q6H7B6L\Administrator" issuerKeyHash="42606c52715d5764c2f9dab5bee6dcd76cc7a67d" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>ZFWmviVXbUoNNcTzjlF6CIAwgFjucuAe0uaxM3GynHY=</DigestValue></Reference></SignedInfo><SignatureValue>QsNzP/zBkv4DjAGj7OxFeO2+ULAJpFzHIQWvvZJ5we+j1FaKDwRRWfPxulWzuN8FufVJxBDfTP1u6P+AjcCXexiR4Z6FqsQIjp+srwZVS/s+5aqE+/g6sM467hj9EoaAT06G3UGd5zfS7jSrml0cixdgdxccDSKXMhrzRKLXaQk=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>23ghUI75yy8GcLhPT5yA+v2ssRfSW+chNqMI+pq5OAr7RXQJOt/+bHdoT9NoS9GQkvblc7ekoUNShIcN601ZZOPgAxkXaQS+La14Wp8GOwnM1qHNJwgla4VAIYjmCj3CUMXLsxspOFVZKRnB6/idYku4Gzhc7NjRBAwe8qWBXaE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="769cb27133b1e6d21ee072ee58803080087a518ef3c4350d4a6d5725bea65564" Description="" Url=""><as:assemblyIdentity name="WordAddIn.vsto" version="1.0.0.0" publicKeyToken="06a92c46db516926" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=DESKTOP-Q6H7B6L\Administrator</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>IGWhRxMC2v3ue2XqINSJOZycFNAcbH/CGBZthW7V9BY=</DigestValue></Reference></SignedInfo><SignatureValue>KNH1p1S/yjcNQCG+fkNvmwbN0kZfwZcenBKArK8+E8ktY0Arv1JPWatVI/ZjnjDilPuSdYpkJr/dOWavuWaPwxyL+x5PoCIGTsq6uXlnTq/ylkqY8mesFYZk6fC7qfSH1zDo7sQljlmpd7NtPq4wzyG2HOGyxytfBw6Hg7TgJ0I=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>23ghUI75yy8GcLhPT5yA+v2ssRfSW+chNqMI+pq5OAr7RXQJOt/+bHdoT9NoS9GQkvblc7ekoUNShIcN601ZZOPgAxkXaQS+La14Wp8GOwnM1qHNJwgla4VAIYjmCj3CUMXLsxspOFVZKRnB6/idYku4Gzhc7NjRBAwe8qWBXaE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIICDTCCAXagAwIBAgIQJpSlsxfGbpRNgyjD5Q/yDjANBgkqhkiG9w0BAQsFADBFMUMwQQYDVQQDHjoARABFAFMASwBUAE8AUAAtAFEANgBIADcAQgA2AEwAXABBAGQAbQBpAG4AaQBzAHQAcgBhAHQAbwByMB4XDTI2MDEyNDAwMzYxNVoXDTI3MDEyNDA2MzYxNVowRTFDMEEGA1UEAx46AEQARQBTAEsAVABPAFAALQBRADYASAA3AEIANgBMAFwAQQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA23ghUI75yy8GcLhPT5yA+v2ssRfSW+chNqMI+pq5OAr7RXQJOt/+bHdoT9NoS9GQkvblc7ekoUNShIcN601ZZOPgAxkXaQS+La14Wp8GOwnM1qHNJwgla4VAIYjmCj3CUMXLsxspOFVZKRnB6/idYku4Gzhc7NjRBAwe8qWBXaECAwEAATANBgkqhkiG9w0BAQsFAAOBgQC3GjWMhEFFrn9PGYrQVGNAaibG1sR/eRX3ZWNRjYLhiqbsdeHvm4CX/W0EWd9yZlbaej87XyeUbX+mC3q3yMFVPCRn/W65WYyBPbWTWmSfU9VLKKULAH6WqjS7CqEU3cQSuKcU6nYG4AJu2/FkQJaA82tr3pvcQD28HmOlDeNh0Q==</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

View File

@@ -0,0 +1 @@
b1dd600e6e5ec491b0bd8e58b71d496f8d22083cd1f3a16f9892bb70b2e31a3f

View File

@@ -0,0 +1,28 @@
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\WordAddIn.dll
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\WordAddIn.pdb
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\WordAddIn.dll.manifest
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\WordAddIn.vsto
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\Microsoft.Office.Tools.Common.v4.0.Utilities.dll
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\Newtonsoft.Json.dll
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\bin\Debug\Newtonsoft.Json.xml
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.AssemblyReference.cache
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.Properties.Resources.resources
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.GenerateResource.cache
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.CoreCompileInputs.cache
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.Up2Date
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.dll
D:\dsWork\aiData\addOne\WordAddIn\WordAddIn\obj\Debug\WordAddIn.pdb
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\WordAddIn.dll
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\WordAddIn.pdb
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\WordAddIn.dll.manifest
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\WordAddIn.vsto
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\Microsoft.Office.Tools.Common.v4.0.Utilities.dll
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\Newtonsoft.Json.dll
D:\dsWork\aiData\WordAddIn\WordAddIn\bin\Debug\Newtonsoft.Json.xml
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.AssemblyReference.cache
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.Properties.Resources.resources
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.GenerateResource.cache
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.CoreCompileInputs.cache
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.csproj.Up2Date
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.dll
D:\dsWork\aiData\WordAddIn\WordAddIn\obj\Debug\WordAddIn.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" />
</packages>

Binary file not shown.

View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,71 @@
# ![Logo](https://raw.githubusercontent.com/JamesNK/Newtonsoft.Json/master/Doc/icons/logo.jpg) Json.NET
[![NuGet version (Newtonsoft.Json)](https://img.shields.io/nuget/v/Newtonsoft.Json.svg?style=flat-square)](https://www.nuget.org/packages/Newtonsoft.Json/)
[![Build status](https://dev.azure.com/jamesnk/Public/_apis/build/status/JamesNK.Newtonsoft.Json?branchName=master)](https://dev.azure.com/jamesnk/Public/_build/latest?definitionId=8)
Json.NET is a popular high-performance JSON framework for .NET
## Serialize JSON
```csharp
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
// {
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
// }
```
## Deserialize JSON
```csharp
string json = @"{
'Name': 'Bad Boys',
'ReleaseDate': '1995-4-7T00:00:00',
'Genres': [
'Action',
'Comedy'
]
}";
Movie m = JsonConvert.DeserializeObject<Movie>(json);
string name = m.Name;
// Bad Boys
```
## LINQ to JSON
```csharp
JArray array = new JArray();
array.Add("Manual text");
array.Add(new DateTime(2000, 5, 23));
JObject o = new JObject();
o["MyArray"] = array;
string json = o.ToString();
// {
// "MyArray": [
// "Manual text",
// "2000-05-23T00:00:00"
// ]
// }
```
## Links
- [Homepage](https://www.newtonsoft.com/json)
- [Documentation](https://www.newtonsoft.com/json/help)
- [NuGet Package](https://www.nuget.org/packages/Newtonsoft.Json)
- [Release Notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Contributing Guidelines](https://github.com/JamesNK/Newtonsoft.Json/blob/master/CONTRIBUTING.md)
- [License](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/json.net)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB