在 MS Office 加载项中获取当前活动的文档文件

Get currently active document file in MS Office Add-In

我正在创建 VSTO 加载项,它将通过 REST API 将文档发送到服务器。 我需要将当前打开的文档(例如 docx)作为文件发送

第一个问题是获取活动文档的全名。 如果找到唯一的方法:

Path.Combine(Globals.ThisAddIn.Application.ActiveDocument.Path,
             Globals.ThisAddIn.Application.ActiveDocument.Name)

此代码可以 return 本地驱动器上的良好路径:D:\Docs\Doc1.docx 但它也可以 return 到云中文档的 HTTP 路径(例如 OneDrive):https://d.docs.live.net/xxxxx/Docs\Doc1.docx

即使只有本地文件我也无法获取该文件的文件。我试过这段代码:

using (var stream = new StreamReader(docFullPath)) { }

对于本地存储的文档,我得到了 System.IO.IOException: The process cannot access the file because it is being used by another process。不足为奇。

如果是云存储文档,我得到了 System.NotSupportedException: The given path's format is not supported。当然!

我相信我做错了,我的目标是可以实现的。 我的问题是:如何在不关闭应用程序的情况下从插件读取 MS Office 应用程序上当前打开的文档文件?

即使您可以访问 ActiveDocument.FullName 指向的文件,也不能保证用户已经将所有更改保存到磁盘,甚至更糟的是,该文档仍处于创建状态并且从未已经保存了。

还有另一种 known/documented 方法来检索打开文档的文件,该方法使用由 Document 对象实现的 IPersistFile COM 接口。以下示例将文档保存到指定位置。这发生在不修改文档的保存状态的情况下,即您在文档打开时获得文档的确切版本(而不是因为它之前已保存到磁盘)并且用户稍后可能仍决定保存文档的可能修改与否。

public static void SaveCopyAs(this Document doc, string path)
{
    var persistFile = (System.Runtime.InteropServices.ComTypes.IPersistFile)doc;
    persistFile.Save(path, false);
}

您可以使用 File.Copy(FullName, <some_temp_filename>) 在文件系统上复制打开的文档,然后将副本发送到您的 REST 服务。即使它仍然在 Word 中以独占方式 reading/writing 开放。