pywin32实现的RTF转DOCX脚本在Windows服务/批处理任务中运行失败求助
解决Windows Server服务/批处理任务中调用Word转换RTF到DOCX失败的问题
问题背景
编写了Python脚本通过pywin32调用Word将RTF转DOCX,CMD中运行正常,但以NSSM服务或批处理任务方式运行时失败,核心原因是Office应用需要交互式桌面会话,而服务/后台任务默认运行在无桌面的系统会话中。
解决方案(尽量不依赖第三方软件)
1. 调整DCOM配置,允许服务账户访问Word
Windows Server中,Office应用的DCOM权限默认限制了后台账户的访问,需手动配置:
- 按下
Win+R输入dcomcnfg打开组件服务。 - 依次展开:组件服务 → 计算机 → 我的电脑 → DCOM配置。
- 找到对应版本的Word对象(如
Microsoft Word 97 - 2003 Document或Microsoft Word Document),右键选择属性:- 安全选项卡:
- 「启动和激活权限」选择「自定义」,点击「编辑」,添加服务/任务运行的账户,赋予本地启动和本地激活权限。
- 「访问权限」同样选择「自定义」,添加账户并赋予本地访问权限。
- 标识选项卡:选择「交互式用户」,或指定一个拥有Word使用权限的本地账户(避免用LocalSystem等系统内置账户)。
- 安全选项卡:
2. 优化脚本,确保后台环境兼容性
修改脚本以适配无桌面环境,同时避免残留Word进程:
import win32com.client import os def ConvertRtfToDocx(path, file): word = None doc = None try: # 初始化Word并隐藏界面 word = win32com.client.Dispatch("Word.Application") word.Visible = False wdFormatDocumentDefault = 16 wdHeaderFooterPrimary = 1 # 安全拼接文件路径 full_rtf_path = os.path.join(path, file) doc = word.Documents.Open(full_rtf_path) # 处理正文内嵌图片的链接保存设置 for pic in doc.InlineShapes: try: if hasattr(pic, "LinkFormat"): pic.LinkFormat.SavePictureWithDocument = True except: pass # 处理页眉内嵌图片的链接保存设置 if doc.Sections.Count > 0: header_range = doc.Sections(1).Headers(wdHeaderFooterPrimary).Range for hPic in header_range.InlineShapes: try: if hasattr(hPic, "LinkFormat"): hPic.LinkFormat.SavePictureWithDocument = True except: pass # 生成DOCX保存路径并完成转换 docx_save_path = os.path.splitext(full_rtf_path)[0] + ".docx" doc.SaveAs(docx_save_path, FileFormat=wdFormatDocumentDefault) finally: # 确保资源正确释放,避免残留Word进程 if doc: doc.Close(SaveChanges=False) if word: word.Quit() del word
3. 配置服务/任务计划的运行参数
- NSSM服务配置:
- 注册服务时,指定运行账户为拥有Word权限的本地账户。
- 在服务属性的「登录」选项卡,勾选「允许服务与桌面交互」。
- 任务计划程序配置:
- 创建任务时,「常规」选项卡选择「不管用户是否登录都要运行」,并勾选「使用最高权限」。
- 「操作」选项卡中,确保程序/脚本指向Python可执行文件,参数为你的脚本路径,起始于脚本所在目录。
关键注意事项
- 服务/任务使用的账户需至少登录过服务器一次,完成Word的首次启动配置(如接受许可协议)。
- 确保服务器已安装完整版本的Microsoft Word,而非仅Viewer版本。
内容的提问来源于stack exchange,提问作者Tech_Napoleon
相关产品推荐
相关产品推荐

