使用win32遍历文件夹对比Word文档遇RPC调用失败错误如何解决
Word批量对比RPC错误修复方案
报错核心原因
你的代码触发RPC调用失败主要是存在以下几个问题:
- 冗余双重循环:你明确说明两个目录下文件命名规则一致,原代码却做了200*200的全量遍历,累计4万次Word实例启动/销毁操作,COM对象频繁创建销毁极容易触发调用失败
- 路径拼接错误:
get_docx_list返回的已经是带完整路径的文件名,后续代码重复拼接目录前缀,导致路径无效无法打开文件 - 资源泄漏:每次对比只关闭Word应用,没有主动关闭打开的原始/修改文档,后台残留大量WINWORD进程占用资源
- Word实例复用缺失:每次循环都新建、销毁Word实例,效率极低且稳定性极差
修复后代码
import win32com.client import os def get_docx_list(dir_path): ''' :param dir_path: 目标目录路径 :return: 目录下所有非临时docx文件的全路径列表 ''' file_list = [] for path, _, files in os.walk(dir_path): for file in files: if file.endswith("docx") and not file.startswith("~"): file_list.append(os.path.join(path, file)) print(f"目录共找到{len(file_list)}个相关文件!") return file_list def main(): modified_path = r"C:\...\Replaced\SWI" # 替换为你的修改版文档目录 original_path = r"C:\...\Replaced\SWI original" # 替换为你的原版文档目录 output_path = modified_path # 对比结果保存目录,可自定义 # 提前加载所有原始文件的文件名映射,方便匹配 original_file_map = {} for ori_file in get_docx_list(original_path): ori_basename = os.path.basename(ori_file) original_file_map[ori_basename] = ori_file # 只创建一次Word实例,全程复用 word_app = win32com.client.gencache.EnsureDispatch("Word.Application") word_app.Visible = False # 后台运行,不显示界面 success_count = 0 fail_count = 0 for idx, modified_file in enumerate(get_docx_list(modified_path), start=1): try: # 按照命名规则匹配对应的原始文件 # 这里假设你的规则是:原始文件名abc.docx,修改后文件名abc_test.docx,可根据实际规则调整 modified_basename = os.path.basename(modified_file) original_basename = modified_basename.replace("_test.docx", ".docx") # 如果你的规则是直接追加test,比如修改后是abctest.docx,就改成: # original_basename = modified_basename.replace("test.docx", ".docx") if original_basename not in original_file_map: print(f"[{idx}] 未找到{modified_basename}对应的原始文件,跳过") fail_count +=1 continue print(f"[{idx}] 正在对比:{modified_basename}") ori_doc = word_app.Documents.Open(original_file_map[original_basename]) mod_doc = word_app.Documents.Open(modified_file) # 执行对比 compare_doc = word_app.CompareDocuments(ori_doc, mod_doc) # 保存对比结果 output_filename = f"{os.path.splitext(modified_basename)[0]}_对比结果.docx" compare_doc.SaveAs(FileName=os.path.join(output_path, output_filename)) # 主动关闭打开的三个文档,释放资源 compare_doc.Close() mod_doc.Close() ori_doc.Close() success_count +=1 except Exception as e: print(f"[{idx}] {modified_basename}对比失败,错误:{str(e)}") fail_count +=1 # 出错时清理当前打开的文档,避免影响后续任务 for doc in word_app.Documents: doc.Close(SaveChanges=False) # 所有任务完成后再关闭Word实例 word_app.Quit() print(f"全部任务完成:成功{success_count}个,失败{fail_count}个") if __name__ == '__main__': main()
使用注意事项
- 运行前先在任务管理器中关闭所有WINWORD进程,避免后台残留进程冲突
- 根据你实际的文件名追加规则调整代码中的文件名替换逻辑,确保能正确匹配到对应的原始文件
- 对比过程中不要操作Word程序,避免打断COM调用
- 如果文档体积较大,可以每处理50份文件重启一次Word实例,进一步降低报错概率
内容的提问来源于stack exchange,提问作者AuPain
相关产品推荐
相关产品推荐

