Word文档移除密码(解除保护/解密)工具——柳涤尘

经常地,某些同事的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

--------------------------------

除非注明,否则均为清风揽月阁原创文章,转载应以链接形式标明本文链接

本文链接:https://www.iimm.ink/69.html

发表评论

滚动至顶部