You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在桌面Word已打开原文档时用Microsoft.Office.Interop.Word对比文档?

解决方案

核心问题分析

你新建的Word.Application是一个独立的Word进程,和桌面已打开的Word进程完全隔离,所以调用ActiveDocument会提示无文档打开。要实现需求,必须获取当前正在运行的Word应用实例,而非创建新实例。

具体实现步骤

  • 用Marshal.GetActiveObject获取已运行的Word进程实例
  • 遍历已打开的文档集合,定位目标原文档
  • 仅打开未在当前进程中打开的修订文档
  • 执行文档对比逻辑

修改后的代码

using System;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Word;

class WordComparer
{
    public static void CompareDocuments(string originalPath, string revisedPath)
    {
        Application wordApp = null;
        Document doc1 = null;
        Document doc2 = null;
        Document comparisonDoc = null;

        try
        {
            // 获取已运行的Word应用实例,若没有则抛出异常
            wordApp = (Application)Marshal.GetActiveObject("Word.Application");
            
            // 从已打开的文档中查找原文档(通过完整路径匹配避免重名)
            foreach (Document doc in wordApp.Documents)
            {
                if (string.Equals(doc.FullName, originalPath, StringComparison.OrdinalIgnoreCase))
                {
                    doc1 = doc;
                    break;
                }
            }

            if (doc1 == null)
            {
                throw new InvalidOperationException("原文档未在当前Word进程中打开");
            }

            // 检查修订文档是否已打开,未打开则打开
            foreach (Document doc in wordApp.Documents)
            {
                if (string.Equals(doc.FullName, revisedPath, StringComparison.OrdinalIgnoreCase))
                {
                    doc2 = doc;
                    break;
                }
            }

            if (doc2 == null)
            {
                object missing = Type.Missing;
                object readOnly = false;
                doc2 = wordApp.Documents.Open(
                    FileName: revisedPath,
                    ReadOnly: readOnly,
                    Visible: false // 修订文档后台打开
                );
            }

            // 执行文档对比
            comparisonDoc = wordApp.CompareDocuments(
                doc1, 
                doc2, 
                WdCompareDestination.wdCompareDestinationNew,
                WdGranularity.wdGranularityWordLevel,
                CompareFormatting: true,
                CompareCaseChanges: true,
                CompareComments: true,
                CompareRevisions: true,
                CompareFields: true,
                CompareTables: true,
                CompareHeaders: true,
                CompareFootnotes: true,
                CompareTextboxes: true,
                CompareEquations: true,
                CompareObjects: true,
                ComparisonName: "",
                ShowSourceDocuments: WdShowSourceDocuments.wdShowSourceDocumentsNone
            );

            // 可选:保存对比结果文档
            // comparisonDoc.SaveAs2(@"C:\Path\To\ComparisonResult.docx");
        }
        catch (COMException ex)
        {
            // 处理未找到Word进程的情况
            Console.WriteLine("未检测到运行中的Word进程:" + ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("对比失败:" + ex.Message);
        }
        finally
        {
            // 仅关闭代码中打开的修订文档,原文档保持打开状态
            if (doc2 != null && string.Equals(doc2.FullName, revisedPath, StringComparison.OrdinalIgnoreCase) && !doc2.Saved)
            {
                doc2.Close(SaveChanges: WdSaveOptions.wdDoNotSaveChanges);
            }

            // 释放COM对象,避免内存泄漏
            if (comparisonDoc != null) Marshal.ReleaseComObject(comparisonDoc);
            if (doc2 != null) Marshal.ReleaseComObject(doc2);
            if (doc1 != null) Marshal.ReleaseComObject(doc1);
            // 不要关闭wordApp,因为它是用户正在使用的进程
        }
    }
}

关键注意事项

  • COM互操作权限:确保程序有足够权限访问Office COM组件,.NET Core项目需在Windows环境下运行(Office互操作仅支持Windows)
  • 文档匹配逻辑:用FullName而非Name匹配,避免同文件名不同路径的混淆
  • 内存泄漏处理:必须手动释放COM对象,否则Word进程可能残留
  • 异常处理:需处理未找到Word进程、原文档未打开等场景

内容的提问来源于stack exchange,提问作者yatin tripathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:30:42