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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:58:25