经常地,某些同事的Word文档经常由于各种原因导致文档被保护,即需要输入密码解除保护后才能修改,而密码又是未知的。几年前,xxc编写了一个,只能解除.doc扩展名的文档,执行速度很快。但近日使用时,经常即使是.doc格式(另存的,不是直接改扩展名),也无法解除保护
基于上述原因,老夫准备自己尝试搞了一个试下:
1、使用python写的,所以生成的exe文件会体积巨大,这个是语言劣势,无法消除,当然也是因为不会搞。所以应该优先使用之前版本的试下,不行再用这个再抢救下看看。执行速度显著的慢。
2、基于.docx格式采用的方法,所以实际解密过程中会先把.wps(必须安装了WPS才行)、.doc、.docx格式先尝试另存为.docx格式,这个过程不快。除这3种格式外,其他格式并不会执行处理。
3、会调用本机Word或WPS,所以需要本机安装有至少一种,如果是.wps格式,则必须安装WPS。
4、解除保护后会在文件所在目录生成一个“解除保护de-”前缀的.docx格式的文档。
5、理论上可以同时拖拽多个文档进行解除保护。
6、电脑DGS等会使文档加密(不安装此类软件无法打开的那种)的软件会导致未知的失败。
7、可能存在一些BUG,仅在我的2台电脑上(window7 和 windows server 2019)试过。
8、将原在公众号发的时候设置的失效日期变更到了2099年。
Word移除密码实现:
# -*- coding:utf-8 -*-
##@柳涤尘2020-11-29
import os,time,shutil,sys
import zipfile
import tkinter
import windnd
from tkinter.messagebox import showinfo
def covert2docx(infile,outfile):
from win32com import client
wordapp=client.Dispatch('Word.Application')
file=wordapp.Documents.Open(infile)
# print(infile,outfile)
file.SaveAs(outfile,12)
file.Close()
wordapp.Quit()
return None
def get_dragged_files_name(files):
arr=[]
for file in files:
file=file.decode('gbk')
if file.upper().endswith('.DOC') or file.upper().endswith('.DOCX') or file.upper().endswith('.WPS'):
arr.append(file)
# print(arr)
return arr
# 压缩docx
def zip_docx(startdir, file_news):
z = zipfile.ZipFile(file_news, 'w', zipfile.ZIP_DEFLATED)
for dirpath, dirnames, filenames in os.walk(startdir):
fpath = dirpath.replace(startdir, '')
fpath = fpath and fpath + os.sep or ''
for filename in filenames:
z.write(os.path.join(dirpath, filename), fpath+filename)
z.close()
def just_do_it(files):
tmppath=os.environ['TMP'].replace('\\','/')
filearr=get_dragged_files_name(files)
resarr=[]
# print(tmppath)
if len(filearr)<1:
showinfo('ERROR',"文件格式不匹配!")
exit()
else:
for file in filearr:
fpath=os.path.dirname(file).replace('\\','/')
fname=file.split('\\')[-1]
fext=fname.split('.')[-1]
fname=fname[:-len(fext)-1]
# print(fpath,fname,fext)
fdocx=tmppath+'/'+fname+'.docx'
zdocx=tmppath+'/iimm/解除保护de-'+fname+'.docx'
zippath=tmppath+'/iimm/zip'
setfpath=zippath+'/word/settings.xml'
# print(file)
try:
print(fdocx)
if os.path.exists(fdocx):
os.remove(fdocx)
covert2docx(file,fdocx)
if os.path.exists(tmppath+'/iimm'):
shutil.rmtree(tmppath+'/iimm')
z=zipfile.ZipFile(fdocx,'r')
z.extractall(path=zippath)
z.close()
with open(setfpath,'r') as f:
xml=f.read()
startpos=xml.find('<w:documentProtection')
endpos=xml[startpos:].find('/>')+startpos
# print(startpos,endpos)
if startpos!=-1:
xml=xml[:startpos]+xml[endpos+1:]
# strs=xml[startpos:endpos+2]
# strs=strs+'x'
# print(strs)
with open(setfpath,'w') as f:
f.write(xml)
zip_docx(zippath,zdocx)
if os.path.exists(fpath+'/解除保护de-'+fname+'.docx'):
os.remove(fpath+'/解除保护de-'+fname+'.docx')
shutil.move(zdocx,fpath)
if os.path.exists(fdocx):
os.remove(fdocx)
if os.path.exists(tmppath+'/iimm'):
shutil.rmtree(tmppath+'/iimm')
# print('xxx')
resarr.append(fname)
except:
showinfo('ERROR','未能成功解除保护')
if os.path.exists(fdocx):
os.remove(fdocx)
if os.path.exists(tmppath+'/iimm'):
shutil.rmtree(tmppath+'/iimm')
exit()
if len(resarr)>0:
showinfo('@柳涤尘','处理成功:\n'+'\n'.join(resarr))
exit()
n_ts=time.time()
dead_time=4093456027 #2099-09-19
if n_ts>dead_time:
showinfo('超出使用期限:2099-09-19')
exit()
else:
# print(sys.version)
tk=tkinter.Tk()
tk.title('Word解除保护@柳涤尘')
tk.geometry('300x150')
tk.resizable(0,0)
l=tkinter.Label(tk,text="将word文档拖拽到此窗口解除保护\n(python写的,运行较慢)")
l.pack()
#打包资源时,打包的资源路径需要这样获取:
if getattr(sys, 'frozen', None):
basedir = sys._MEIPASS
else:
basedir = os.path.dirname(__file__)
imagepath=os.path.join(basedir, 'qflyg.gif')
canvas=tkinter.Canvas(tk,height=150,width=300)
image_file=tkinter.PhotoImage(file=imagepath)
image=canvas.create_image(250,40,image=image_file)
canvas.pack()
windnd.hook_dropfiles(tk,func=just_do_it)
tk.mainloop()
--------------------------------虽然比较弱鸡,也保存下记录学习过程。源代码(也可以在这里直接下载exe文件使用):liudichen/DocUnprotect (github.com) 或者到百度网盘下载: https://pan.baidu.com/s/1QAqOCiU7AmEH8xjtq1iXiw 提取码: rzur
除非注明,否则均为清风揽月阁原创文章,转载应以链接形式标明本文链接