Vogliamo automatizzare il processo di rimozione della protezione dai file Word utilizzando il nostro amato Python. Questo articolo si ricollega al procedimento già illustrato in precedenza in [word] Rimuovere “Limita modifica” da un file docx di Word
Per i dettagli della procedura rimando all’articolo precedente, qui vedremo esclusivamente la parte che riguarda Python.
In Python vogliamo realizzare uno script che permetta o dal prompt dei comandi, oppure trascinandoci sopra un file, di sbloccare un file Word al quale sia applicata la protezione contro le modifiche.
Quello che vogliamo ottenere alla fine è qualcosa di simile:

Oppure un eseguibile sopra il quale sia possibile trascinare il file da sbloccare.

Seguono i commenti nel codice:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import sys import zipfile import os import shutil # costruiamo il main def main():     # in caso di un qualsiasi errore non gestito     try:         # controlliamo se c'è il secondo argomento, ricordando che gli argomenti sono:         # 0 - nome dello script o dell'eseguibile         # 1 - primo argomento, in questo caso il percorso del file         # la lunghezza quindi degli argomenti passati dev'essere almeno 2         if len(sys.argv) < 2:             print("Trascina un file sull'eseguibile")             return         # se c'è il secondo argomento supponiamo che sia il percorso al file         else:             # preleviamo il percorso al file             file_path = sys.argv[1]             print(f"Percorso del file: {file_path}")             print("Inizio modifica file...")             # definiamo una cartella temporanea per l'estrazione             temp_dir = "temp_extract"             try:                 # creiamo tale cartella, se già esiste andiamo avanti                 os.makedirs(temp_dir, exist_ok=True)             except:                 print("Errore 1: impossibile creare cartella, permesso negato")                 return             try:                 # estraiamo tutto il file docx, trattandolo come se fosse un file zip                 # ricordiamoci che a tutti gli effetti è un file zip rinominato                 with zipfile.ZipFile(file_path, 'r') as fp:                     fp.extractall(temp_dir)             except:                 print("Errore 2: impossibile scompattare!")                 return             # in ogni file word corretto dovrà essere il file settings.xml che andremo a modificare             xml_file = "temp_extract/word/settings.xml"             try:                 # apriamo il file xml e leggiamo tutto il contenuto                 with open(xml_file,'r') as fp:                     contenuto = fp.read()                 # sostituiamo il parametro enforcement impostandolo su false                 # ricordiamoci che il parametro può comparire configurato o come true o come 1                 # quindi tentiamo entrambe le sostituzioni, ovviamente avremmo potuto usare                 # la librerira xml, oppure un riconoscimento con stringhe regolari, ma perché                 # scomodarsi se possiamo fare le cose in modo bovino?                 contenuto = contenuto.replace('w:enforcement="true"','w:enforcement="false"')                 contenuto = contenuto.replace('w:enforcement="1"','w:enforcement="false"')                 # riscriviamo il file xml                 with open(xml_file,'w') as fp:                     fp.write(contenuto)                 print("Chiusura file modificato...")             except:                 print("Errore 3: impossibile modificare il file!")                 return             # predisponiamo il nome del file sbloccato             file_name = "sbloccato-" + os.path.basename(file_path)             try:                 # ricreiamo tutto il file zip di prima, con il nuovo nome, applicando la compressione                 # ATTENZIONE: senza il parametro di compressione il file risultante potrebbe essere                 # molto più grande di quello di partenza (circa 10x)                 with zipfile.ZipFile(file_name,'w', compression=zipfile.ZIP_DEFLATED) as fp:                     # percorriamo le cartelle in cerca di file                     for root, _, files in os.walk(temp_dir):                         # per ogni file che troviamo                         for file in files:                             # creiamo il percorso del file                             fpath = os.path.join(root,file)                             # prendiamo il percorso reale                             arcname = os.path.relpath(fpath,temp_dir)                             # aggiungiamo il file allo zip                             fp.write(fpath, arcname)             except:                 print("Errore 4: impossibile ricomporre!")                 return             try:                 # cancelliamo la cartella temporanea, usando shutil possiamo rimuovere tutta la cartella                 # anche se dentro ci sono altri file e cartelle, cosa che os.rmdir non permette di fare                 shutil.rmtree(temp_dir)             except Exception as e:                 print(f"Errore 5: impossibile pulire! {e}")                 return             print("File modificato con successo in: %s" % file_name)     except:         print("Errore 0: impossibile eseguire") if __name__ == "__main__":     print("WordUnlocker v1.0.0")     # eseguiamo il file main     main()     # questo ci serve solo per tenere aperto il prompt quanto basta per informare l'utente     # alla pressione di INVIO il programma effettivamente terminerà     scelta = input("Premi invio per chiudere...") | 
Una volta scritto il codice in un file WordUnlocker.py salviamo il tutto e procediamo a creare il file eseguibile.
Per creare l’eseguibile utilizziamo pyinstaller. Possiamo installarlo utilizzando il comando PIP:
| 1 | pip install -U pyinstaller | 
Dobbiamo preparare un file di versione che chiameremo file_version_info.txt, che sarà strutturato nel modo seguente:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | VSVersionInfo(   ffi=FixedFileInfo(     filevers=(1, 0, 0, 0),     prodvers=(1, 0, 0, 0),     mask=0x3f,     flags=0x0,     OS=0x40004,     fileType=0x1,     subtype=0x0,     date=(0, 0)     ),   kids=[     StringFileInfo(       [       StringTable(         u'040904B0',         [StringStruct(u'CompanyName', u'Petar Karan'),         StringStruct(u'FileDescription', u'MS Office Word Unlocker'),         StringStruct(u'FileVersion', u'1.0.0.0 (20 febbraio 2025)'),         StringStruct(u'InternalName', u'wordunlocker'),         StringStruct(u'LegalCopyright', u'\xa9 Petar Karan. All rights reserved. https://petarkaran.it/'),         StringStruct(u'OriginalFilename', u'WordUnlocker.exe'),         StringStruct(u'ProductName', u'Word Unlocker'),         StringStruct(u'ProductVersion', u'1.0.0.0')])       ]),      VarFileInfo([VarStruct(u'Translation', [1033, 1200])])   ] ) | 
Adesso possiamo compilare l’eseguibile con il seguente commando eseguito dal terminale sulla cartella del file di Python:
| 1 | pyinstaller --clean --onefile .\WordUnlocker.py -i wordunlocker.png --version-file file_version_info.txt | 
Fatto tutto questo non ci rimane che firmare digitalmente l’eseguibile. Per farlo abbiamo bisogno del comando signtool disponibile in Windows SDK.
Affinché signtool funzioni è necessario aggiungerlo al PATH di sistema, per farlo apriamo il Pannello di controllo > Sistema > Impostazioni avanzate > Variabili di ambiente e aggiungiamo a PATH il percorso di installazione corretto C:\Program Files (x86)\Windows Kits\10\App Certification Kit
Questo percorso potrebbe cambiare in base all’installazione del SDK fatta in precedenza.
Una volta che tutto è pronto spostiamoci nella cartella dove abbiamo il nostro eseguibile compilato ed eseguiamo:
| 1 | signtool sign /a /t http://timestamp.digicert.com /fd SHA256 /v .\WordUnlocker.exe | 
Fatto tutto questo avremo il nostro file correttamente firmato. E’ possibile scaricare il file eseguibile dal link seguente:
