使用Python的win32com解除DOC/DOCX保护失败求助
问题分析与解决方案
核心代码问题
你的unprotect_file函数存在关键错误:doc.Unprotect仅引用了方法对象,未实际调用该方法,且未传入文档保护密码(若文档设置了保护密码),这就是代码无报错但无法解除保护的直接原因。
修正后的代码
修改解除保护的核心逻辑,补充方法调用括号并传入密码参数:
import win32com.client def protect_file(pFileName, pPassword): word = win32com.client.gencache.EnsureDispatch('Word.Application') word.Visible = False doc = word.Documents.Open(pFileName, PasswordDocument=pPassword) doc.Protect(Type=2, NoReset=True, Password=pPassword) doc.Save() doc.Close() word.Quit() def unprotect_file(pFileName, pPassword): word_app = win32com.client.gencache.EnsureDispatch('Word.Application') word_app.Visible = False doc = None try: doc = word_app.Documents.Open(pFileName, PasswordDocument=pPassword) protection_type = doc.ProtectionType if protection_type != -1: if protection_type == 2: print(f'Protection Type : {protection_type} -> wdAllowOnlyComments' ) elif protection_type == 3: print(f'Protection Type : {protection_type} -> wdAllowOnlyRevisions' ) elif protection_type == 4: print(f'Protection Type : {protection_type} -> wdAllowOnlyFormFields' ) # 关键修正:调用Unprotect方法并传入保护密码 doc.Unprotect(Password=pPassword) doc.Save() print(f'Document unprotected and saved !') else: print(f'{pFileName} is not protected !') except Exception as e: print(f'Error : {e}') finally: if doc: doc.Close(SaveChanges=True) word_app.Quit()
其他免费替代方案
若win32com仍无法解决问题,可尝试以下免费方案:
1. LibreOffice命令行无界面处理
利用LibreOffice的命令行工具解除保护(需知晓保护密码):
libreoffice --headless --convert-to docx:"MS Word 2007 XML" --unprotect-password=你的保护密码 目标文档路径
执行后会生成一个解除保护的新文档。
2. python-docx修改DOCX内部结构(无密码保护场景)
针对无密码的DOCX格式保护,可直接修改文档XML结构移除保护:
from docx import Document def unprotect_docx(file_path): doc = Document(file_path) # 定位并移除保护节点 protection_node = doc.settings.element.find('.//w:documentProtection') if protection_node is not None: doc.settings.element.remove(protection_node) # 保存解除保护后的文档 doc.save(f'unprotected_{file_path}') unprotect_docx('protected.docx')
注意:此方法仅适用于未设置密码的格式保护,若有密码需先解密。
内容的提问来源于stack exchange,提问作者Ricardo Pascoal
相关产品推荐
相关产品推荐

