c# - 如何在插件内获取 MS Word 文件二进制文件

标签 c# .net ms-word vsto

我正在为 Microsoft Word 开发 VSTO 插件。该插件的功能之一是它可以处理远程服务器上文档的打开和保存。进行 Web 服务调用以从远程服务器获取文件并使用插件打开它很容易,但我无法找到将更新的文件发送回服务器以远程保存的方法。我尝试像这样附加到 DocumentBeforeSave 事件

private void Application_DocumentBeforeSave(Document doc, ref bool SaveAsUI, ref bool Cancel)
{
    doc.Save();
    var docuBinary = File.ReadAllBytes(doc.FullName);
    // call method to upload binary
}

但是我收到一个 IO 异常,表示另一个进程正在使用该文件(我假设该进程是 word)。我尝试过类似的策略,其中涉及具有不同文件名的 SaveAs2 方法,但我得到了相同的错误。我还尝试手动创建文件流并从中读取,但出现了相同的错误。

我已经找到一种工作方法,即保存文档,然后将其复制到临时文件,然后读取该临时文件内容并上传。所以基本上是这样的

private void Application_DocumentBeforeSave(Document doc, ref bool SaveAsUI, ref bool Cancel)
{
    doc.Save();
    string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    File.Copy(doc.FullName, tempFile);
    var docuBinary = File.ReadAllBytes(tempFile);
    // upload...
}

我不确定为什么允许 File.Copy 访问该文件,而其他方法则不允许(也许 File.Copy 会访问操作系统?)但是,我只是不允许我是这种方法的忠实粉丝,因为它看起来确实很老套,而且注定会以某种不可预见的方式失败。

那么有没有更好的办法呢?是否有某种我不知道的方法可以将文件发送到 URL,是否有方法从 Document 对象(或其他 .NET 对象)获取原始二进制文件?

最佳答案

尽管您使用 File.Copy 的方法有效,但还有另一种鲜为人知的方法来检索当前打开的文档的文件,该方法使用 IPersistFile COM 接口(interface)。该接口(interface)由Document 对象实现。

以下示例将文档保存到指定位置。发生这种情况时无需修改文档的保存状态,即您获得文档打开时的确切版本(而不是之前保存到磁盘的版本),并且用户稍后仍可能决定保存文档的可能修改或不。

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

关于c# - 如何在插件内获取 MS Word 文件二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48528173/

相关文章:

c# - 通过数据网格将数据保存到数据库

java - 洋葱架构 : Should UI project have access to Domain Layer?

c# - MemoryStream.SetLength(0) 和 MemoryStream.Capacity = 0 不会清除已用内存

performance - 对于某些用户配置文件,在Powershell中使用Word.Application的速度非常慢

java - Doc4j - 使用文档中的表格将 docx 转换为 PDF 时遇到问题

c# - 欧拉计划的问题问题 12

c# - 如何自动调整 RDLC 报告中的列宽

java - 如何使用 docx4j 从模板创建一个新词

c# - Windows 更新应用程序

c# - 如何在不重置堆栈跟踪的情况下抛出异常?