Last active
November 8, 2017 20:31
-
-
Save tallpeak/eb794d76ebb57a505a93c6ff5212ac15 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CreateExcelUnlocker.ps1 | |
# Originally by Anton P. ([email protected]) | |
# see http://lbeliarl.blogspot.com/2014/03/excel-removing-password-from-vba.html | |
# Powershell conversion by Aaron West, [email protected] | |
$strFile = "ExcelUnlockerFromPowershell.xlsm" | |
$strPath = "$($env:TEMP)\$strFile" | |
$xl = New-Object -ComObject Excel.Application | |
$xl.Application.EnableEvents = $False | |
$xl.Visible = $True | |
$xl.DisplayAlerts = $True | |
#$xl.DefaultSaveFormat = 52 #xlOpenXMLWorkbookMacroEnabled | |
$wb = $xl.Workbooks.Add() | |
$ws = $wb.Worksheets.Item(1) | |
$ws.Name = "Sheet1" | |
$ws.Cells.Item(2,3) = "Remove VBA Project protection" | |
$ws.Cells.Item(3,3) = "Remove Workbook Protection" | |
$ws.Cells.Item(4,3) = "Remove WorkSheets Protection" | |
$ws.DrawingObjects().Delete() | |
# note the parentheses; CheckBoxes is an IDispatch (a Com function interface) | |
$cb1 = $ws.CheckBoxes().Add(18, 15, 24, 17) | |
$cb1.Name = "CheckVBA" | |
$cb1.Text = "" | |
$cb1.LinkedCell() = "`$B`$2" | |
$cb1.Value() = 1 | |
$ws.Names.Add("CheckVBA","=Sheet1!R2C2") | |
$cb2 = $ws.CheckBoxes().Add(18, 30, 24, 17) | |
$cb2.Name = "CheckWS" | |
$cb2.Text = "" | |
$cb2.LinkedCell() = "`$B`$3" | |
$cb2.Value() = 0 | |
$ws.Names.Add("CheckWS","=Sheet1!R3C2") | |
$cb3 = $ws.CheckBoxes().Add(18, 45, 24, 17) | |
$cb3.Name = "CheckWB" | |
$cb3.Text = "" | |
$cb3.LinkedCell() = "`$B`$4" | |
$cb3.Value() = 0 | |
$ws.Names.Add("CheckWB","=Sheet1!R4C2") | |
$btn = $ws.Buttons().Add(95.25, 78.75, 103.5, 46.5) | |
$btn.Name = "btnSelectFile" | |
$btn.Text = "Select File" | |
$btn.OnAction = "GeneralSub" | |
Push-Location $env:TEMP | |
$codeModule_auxiliaryFuncs = @" | |
Attribute VB_Name = "auxiliaryFuncs" | |
Option Base 1 | |
Function ProtectedVBProject(ByRef wb As Workbook) As Boolean | |
' returns TRUE if the VB project in the active document is protected | |
Dim VBC As Integer | |
VBC = -1 | |
On Error Resume Next | |
VBC = wb.VBProject.VBComponents.Count | |
On Error GoTo 0 | |
If VBC = -1 Then | |
ProtectedVBProject = True | |
Else | |
ProtectedVBProject = False | |
End If | |
End Function | |
Function PrWB(ByRef wb As Workbook) As Boolean | |
PrWB = False | |
If wb.ProtectWindows Then PrWB = True | |
If wb.ProtectStructure Then PrWB = True | |
If PrWB = True Then | |
'try for password protection | |
On Error Resume Next | |
wb.Unprotect | |
If Err.Number = 0 Then PrWB = False | |
On Error GoTo 0 | |
End If | |
End Function | |
Function PrWSheets(ByRef wb As Workbook) As Boolean | |
PrWSheets = False | |
''Arrays for storing protected wsheets | |
i = 0 | |
For Each SH In wb.Sheets | |
If SH.ProtectContents Or SH.ProtectDrawingObjects Or SH.ProtectScenarios Then | |
i = i + 1 | |
ReDim Preserve ProtectedSheets(i) | |
ProtectedSheets(i) = SH.Index | |
PrWSheets = True | |
End If | |
Next | |
End Function | |
Function copy_excel_file(file_to_copy) | |
''Create Scripting Object | |
'Dim FSO As Object | |
Set FSO = CreateObject("scripting.filesystemobject") | |
'Define new name | |
UnprotecedFilePath = FSO.GetParentFolderName(file_to_copy) & "\Unprotected_" & FSO.GetFileName(file_to_copy) | |
''Check if file already copied | |
If CopiedExcel = False Then | |
On Error Resume Next | |
''Copy | |
FSO.CopyFile file_to_copy, UnprotecedFilePath, True | |
''Check for access error | |
If Err.Number <> 0 Then | |
MsgBox "You have no Write access to the folder: '" & FSO.GetParentFolderName(file_to_copy) & "'", vbCritical, "Excel Unlocker" | |
copy_excel_file = "" | |
Exit Function | |
End If | |
On Error GoTo 0 | |
'Save flag | |
CopiedExcel = True | |
End If | |
Set FSO = Nothing | |
''return path | |
copy_excel_file = UnprotecedFilePath | |
End Function | |
Function rename_to_zip(file_to_rename) | |
''Create Scripting Object | |
Dim FSO As Object | |
Set FSO = CreateObject("scripting.filesystemobject") | |
''Create new name | |
ZIPFilePath = FSO.GetParentFolderName(file_to_rename) & "\" & FSO.GetBaseName(file_to_rename) & ".zip" | |
''Check if file already renamed | |
If RenamedZIP = False Then | |
'chekc if file with such name exists | |
If FSO.FileExists(ZIPFilePath) Then FSO.DeleteFile ZIPFilePath, True | |
'Change extension | |
FSO.MoveFile file_to_rename, ZIPFilePath | |
'Save flag | |
RenamedZIP = True | |
End If | |
Set FSO = Nothing | |
''Return path | |
rename_to_zip = ZIPFilePath | |
End Function | |
Function create_TMP_folder() | |
''Path to tmp folder | |
FileNameFolder = Environ("tmp") & "\UnlockFolderTMP" | |
If CreatedTMPFolder = False Then | |
''Create Scripting Object | |
'Dim FSO As Object | |
Set FSO = CreateObject("scripting.filesystemobject") | |
''Delete if previous files exists | |
Do While FSO.FolderExists(FileNameFolder & "\") | |
FSO.deletefolder FileNameFolder | |
DoEvents | |
Application.Wait (Now + TimeValue("0:00:01")) '' wait until deletion is done | |
Loop | |
'Make the tmp folder in User tmp | |
FSO.CreateFolder FileNameFolder | |
'Destroy FSO | |
Set FSO = Nothing | |
'Set Flag | |
CreatedTMPFolder = True | |
End If | |
create_TMP_folder = FileNameFolder | |
End Function | |
Function ChangeDPBValue(PathToBinFile As String, HASHPassword As String) As String | |
''Dim adoStream As ADODB.Stream | |
''Dim adoBin As ADODB.Stream | |
Dim PasswordArrayByte() As Byte | |
Set adoStream = CreateObject("ADODB.Stream") | |
Set adoBin = CreateObject("ADODB.Stream") | |
ReDim PasswordArrayByte(Len(HASHPassword)) | |
''Convert String to byte | |
For i = 1 To Len(HASHPassword) | |
PasswordArrayByte(i) = Asc(Mid(HASHPassword, i, 1)) | |
Next i | |
''Read TXT data fine 'DPB' value | |
With adoStream | |
.Mode = 3 'adModeReadWrite | |
.Type = 2 'adTypeText | |
.Charset = "us-ascii" | |
.Open | |
.LoadFromFile (PathToBinFile) | |
bytes = .ReadText | |
''Find Start of Value pos | |
StartPosVal = InStr(1, bytes, "DPB=", vbTextCompare) + 5 | |
''IF there is no DPB value | |
If StartPosVal = 5 Then | |
.Close | |
Set adoStream = Nothing | |
Set adoBin = Nothing | |
ChangeDPBValue = "VBA Protection Not found" | |
Exit Function | |
End If | |
''Find End of Value pos | |
EndPosVal = InStr(StartPosVal, bytes, """", vbTextCompare) - 1 | |
'Define lenght | |
ValLength = EndPosVal - StartPosVal + 1 | |
If Len(HASHPassword) < ValLength Then | |
'add additional '0' if coded password is longer | |
ReDim Preserve PasswordArrayByte(Len(HASHPassword) + ValLength - Len(HASHPassword)) | |
For i = Len(HASHPassword) + 1 To UBound(PasswordArrayByte) | |
PasswordArrayByte(i) = Asc(0) | |
Next i | |
End If | |
.Close | |
End With | |
''Read binary data | |
With adoStream | |
.Mode = 3 'adModeReadWrite | |
.Type = 1 'adTypeBinary | |
.Open | |
.LoadFromFile (PathToBinFile) | |
''Create empty stream object | |
With adoBin | |
.Mode = 3 'adModeReadWrite | |
.Type = 1 'adTypeBinary | |
.Open | |
End With | |
'copy first part of bytes (till start of 'DPB' value) | |
.Position = 0 | |
.CopyTo adoBin, StartPosVal - 1 | |
'copy new DPB value | |
adoBin.Write (PasswordArrayByte) | |
'copy remaining part of bytes (after 'DPB' value) | |
.Position = EndPosVal ''Set position to remaining part | |
.CopyTo adoBin | |
'save to file | |
adoBin.SaveToFile PathToBinFile, 2 'adSaveCreateOverWrite | |
adoBin.Close | |
.Close | |
End With | |
Set adoStream = Nothing | |
Set adoBin = Nothing | |
ChangeDPBValue = "" | |
End Function | |
'Sub Auto_Open() | |
' | |
''''Add ADO library if required--------------------------------------------- | |
''ADOAssigned = False | |
'' | |
''For i = 1 To ThisWorkbook.VBProject.References.Count | |
'' ''Debug.Print ThisWorkbook.VBProject.References.Item(i).Name | |
'' If ThisWorkbook.VBProject.References.Item(i).Name = "ADODB" Then | |
'' ADOAssigned = True | |
'' End If | |
''Next i | |
'' | |
''If ADOAssigned = False Then | |
'' ThisWorkbook.VBProject.References.AddFromFile Environ("CommonProgramFiles") & "\System\ado\msado15.dll" | |
''End If | |
' | |
' | |
'End Sub | |
"@ | |
$codeModule_mainFuncs = @" | |
Attribute VB_Name = "mainFuncs" | |
''Created by Anton P. ([email protected]) | |
Option Base 1 | |
Declare Function GetTickCount Lib "kernel32.dll" () As Long | |
Public CopiedExcel As Boolean | |
Public RenamedZIP As Boolean | |
Public CreatedTMPFolder As Boolean | |
Public ProtectedSheets() As Long | |
Sub GeneralSub() | |
CopiedExcel = False | |
RenamedZIP = False | |
CreatedTMPFolder = False | |
'Check if any selection exists | |
If (Range("Sheet1!CheckVBA").Value Or Range("Sheet1!CheckWB").Value Or Range("Sheet1!CheckWS").Value) = False Then | |
MsgBox "Please select at least one checkBox!", vbInformation, "Excel Unlocker" | |
Exit Sub | |
End If | |
ChDir (Environ("USERPROFILE") & "\Desktop") | |
'Select the file | |
Fname = Application.GetOpenFilename(filefilter:="Excel files (*.xlsx; *.xlsm), *.xlsx; *.xlsm", MultiSelect:=False) | |
'Check if file selected | |
If Fname = False Then | |
Exit Sub | |
End If | |
''Check if workBook has password for opening | |
On Error Resume Next | |
Dim tmpWB As Workbook | |
''Disable AutoRun macro | |
Application.EnableEvents = False | |
Set tmpWB = Workbooks.Open(Fname, ReadOnly:=True, Password:="", UpdateLinks:=False, IgnoreReadOnlyRecommended:=True) | |
''Returnt original settings (AutoRun macro) | |
Application.EnableEvents = True | |
If Err.Number > 0 Then | |
MsgBox "Selected Workbook is encrypted (Password for Openning)!" & vbCrLf & "This program doesn't works with such files.", vbCritical, "Excel Unlocker" | |
Exit Sub | |
End If | |
On Error GoTo 0 | |
''Check if WorkBook is in Shared mode | |
If tmpWB.MultiUserEditing = True Then | |
''Close WorkBook | |
tmpWB.Close saveChanges:=False | |
MsgBox "Selected Workbook is in Shared Mode!" & vbCrLf & "Please change mode to Exclusive (non Shared) and try again", vbExclamation, "Excel Unlocker" | |
Exit Sub | |
End If | |
''Check if VBProjec protected | |
ProjectProtected = ProtectedVBProject(tmpWB) | |
''Check if WorkBook is protected | |
WBookProtected = PrWB(tmpWB) | |
''Checx if Sheets is protected | |
WBookSheetsProtected = PrWSheets(tmpWB) | |
''Close WorkBook | |
tmpWB.Close saveChanges:=False | |
Set tmpWB = Nothing | |
'String for output msgs | |
Dim OutMSG As String | |
OutMSG = "" | |
''Create Scripting Object | |
Dim FSO As Object | |
Set FSO = CreateObject("scripting.filesystemobject") | |
''Call procedure for each action----------------------------- | |
''WorkBook------------------------------ | |
If Range("Sheet1!CheckWB").Value = True Then | |
If WBookProtected = True Then | |
OutMSG = UnprotectWBook(Fname) | |
Else | |
OutMSG = OutMSG & vbCrLf & "Selected WorkBook has no WorkBook Password Protection." | |
End If | |
'ChangeWBStatus | |
WBookProtected = False | |
End If | |
''Vba----------------------------------- | |
If Range("Sheet1!CheckVBA").Value = True Then '''And FSO.GetExtensionName(Fname) = "xlsm" | |
'Check whether WorkBook has VBA Project protection | |
If ProjectProtected = True Then | |
'Check whether WorkBook has Password Protection (internal ZIP encryption) | |
If WBookProtected = True Then | |
OutMSG = OutMSG & vbCrLf & UnprotectWBook(Fname) | |
End If | |
''Call VBA unlock | |
OutMSG = OutMSG & vbCrLf & ChangePasswordForVBA(Fname) | |
Else | |
OutMSG = OutMSG & vbCrLf & "Selected WorkBook has no VBA Project protection." | |
End If | |
End If | |
''WorkSheet---------------------------- | |
If Range("Sheet1!CheckWS").Value = True Then | |
If WBookSheetsProtected = True Then | |
'Check whether WorkBook has Password Protection (internal ZIP encryption) | |
If WBookProtected = True Then | |
OutMSG = OutMSG & vbCrLf & UnprotectWBook(Fname) | |
End If | |
''Call Sheets unlock | |
OutMSG = OutMSG & vbCrLf & UnprotectWSheets(Fname) | |
Else | |
OutMSG = OutMSG & vbCrLf & "Selected WorkBook has no WorkSheets Protection." | |
End If | |
End If | |
''Check if returning to previous state is required | |
If RenamedZIP = True Then | |
''Rename back to .xlsm file | |
FSO.GetFile(rename_to_zip(copy_excel_file(Fname))).Name = FSO.GetFileName(copy_excel_file(Fname)) | |
''Delete tmp files-------------------------- | |
' If FSO.FolderExists(FileNameFolder & "\") Then | |
' FSO.deletefolder FileNameFolder | |
' End If | |
End If | |
If RenamedZIP Or CopiedExcel Then | |
OutMSG = OutMSG & vbCrLf & vbCrLf & "Unlocked file saved under the name: '" & "Unprotected_" & FSO.GetFileName(Fname) & "' in the same folder" | |
End If | |
Set FSO = Nothing | |
MsgBox OutMSG, vbInformation, "Excel Unlocker" | |
End Sub | |
Function ChangePasswordForVBA(Fname As Variant) As String | |
Application.StatusBar = "Resetting VBA Project password..." | |
''Copy Excel file and Rename to ZIP | |
name_of_exel_file = copy_excel_file(Fname) | |
If name_of_exel_file = "" Then ''Missing Write acces | |
ChangePasswordForVBA = "Missing Write access" | |
Exit Function | |
End If | |
CopyFname = rename_to_zip(name_of_exel_file) | |
''TMP Folder | |
FileNameFolder = create_TMP_folder | |
'Object for work with ZIP file | |
Set oApp = CreateObject("Shell.Application") | |
''Set to false | |
ProjectFileFound = False | |
''Cycle trought Zip archive | |
For Each fileNameInZip In oApp.Namespace(CopyFname).items | |
'find 'xl' folder | |
If fileNameInZip = "xl" Then | |
'find vbaProject.bin | |
For Each subFile In fileNameInZip.Getfolder.items | |
'extract 'vbaProject.bin' file | |
If subFile = "vbaProject.bin" Then | |
''Move bin file to tmp folder | |
oApp.Namespace(FileNameFolder).movehere subFile | |
ProjectFileFound = True | |
Exit For | |
End If | |
Next | |
End If | |
Next | |
''HASH for Password = 'macro' | |
Dim PasswordString As String | |
PasswordString = "282A84CBA1CBA1345FCCB154E20721DE77F7D2378D0EAC90427A22021A46E9CE6F17188A" | |
''if VbaProject exists | |
If ProjectFileFound = True Then | |
tmpMSG = "" | |
tmpMSG = ChangeDPBValue(FileNameFolder & "\vbaProject.bin", PasswordString) ''DPB change | |
''Overwirte existing vbaProject.bin file | |
oApp.Namespace(CopyFname).items.Item("xl").Getfolder.CopyHere FileNameFolder & "\vbaProject.bin" | |
'Keep script waiting until Compressing is done | |
On Error Resume Next | |
Do Until oApp.Namespace(CopyFname).items.Item("xl").Getfolder.items.Item("vbaProject.bin").Name = "vbaProject.bin" | |
Application.Wait (Now + TimeValue("0:00:01")) | |
Loop | |
On Error GoTo 0 | |
If tmpMSG = "" Then | |
ChangePasswordForVBA = "Password for VbaProject: 'macro'" | |
Else | |
ChangePasswordForVBA = tmpMSG | |
End If | |
Else | |
ChangePasswordForVBA = "File don't have VbaProject!" | |
End If | |
Set oApp = Nothing | |
Application.StatusBar = "" | |
End Function | |
Sub generateHashtable() | |
Application.Calculation = xlCalculationManual | |
Dim htsht As Worksheet | |
Set htsht = ThisWorkbook.Sheets.Add() | |
htsht.Name = "hash_table" | |
htsht.Visible = xlSheetHidden | |
Dim r As Range | |
Set r = htsht.Cells(1, 1) | |
'Value RND_pos | |
r.Value = "Value" | |
r.Offset(0, 1).Value = "RND_pos" | |
Set r = htsht.Cells(2, 1) | |
Dim a As Integer, b As Integer, c As Integer, rw As Long | |
rw = 0 | |
For a = 64 To 95 | |
For b = 64 To 95 | |
Dim ab As String | |
ab = Chr(a) & "...." & Chr(b) & "...." | |
For c = 64 To 95 | |
Dim abc As String | |
abc = ab & Chr(c) | |
r.Offset(rw, 0).Value = abc | |
'r.Offset(rw, 1).Formula = "=rand()" | |
rw = rw + 1 | |
Next | |
Next | |
Next | |
htsht.Range("B2:B32769").Formula = "=rand()" | |
ThisWorkbook.Sheets("Sheet1").Activate | |
htsht.Visible = xlSheetVisible | |
Application.Calculation = xlCalculationAutomatic | |
End Sub | |
Function UnprotectWBook(Fname As Variant) As String | |
Dim UL As Workbook | |
Dim lockedWB As Workbook | |
''Remember this WB name | |
Set UL = ThisWorkbook | |
'How to Regenerate hash values with Haskell: | |
'ghci: | |
'Prelude System.IO> withFile "c:\\temp\\ExcelHashValues.txt" WriteMode (\h -> hPutStr h $ concat [[toEnum a]++"...."++[toEnum b]++"...." ++ [toEnum c] ++ "\n" | a <- [64..95], b<-[64..95], c<-[64..95] ]) | |
' then put that text into column a1 | |
' and put =rand() in b1:b32769 | |
Dim foundHashTable As Boolean | |
foundHashTable = False | |
Dim ht | |
On Error Resume Next | |
Set ht = UL.Worksheets.Item("hash_table") | |
foundHashTable = True | |
On Error GoTo 0 | |
If Not foundHashTable Then | |
generateHashtable | |
'MsgBox "Hashtable removed; macro disabled" | |
'Exit Function | |
End If | |
LockedWBName = copy_excel_file(Fname) | |
If LockedWBName = "" Then ''Missing Write access | |
UnprotectWBook = "Missing Write access" | |
Exit Function | |
End If | |
''Disable AutoRun macro | |
Application.EnableEvents = False | |
''Disable Alerts | |
Application.DisplayAlerts = False | |
''Dissable screen updating | |
Application.ScreenUpdating = False | |
''Open Locked WB | |
On Error Resume Next ''Prevent error for WriteProtection Password | |
Set lockedWB = Workbooks.Open(LockedWBName, notify:=False, WriteResPassword:="", UpdateLinks:=False, IgnoreReadOnlyRecommended:=True) | |
''Check for Write password--------------- | |
If Err.Number <> 0 Then | |
'Open original file | |
Set lockedWB = Workbooks.Open(Fname, ReadOnly:=True, UpdateLinks:=False, IgnoreReadOnlyRecommended:=True) | |
'Save as Unlocked | |
lockedWB.SaveAs LockedWBName, WriteResPassword:="", ReadOnlyRecommended:=False | |
End If | |
On Error GoTo 0 | |
''Returnt original settings (AutoRun macro) | |
Application.EnableEvents = True | |
''Randomize HASH values to improve chance of quick break | |
Sheet3.Calculate | |
'''HASH values calculated based on algorithm described here: | |
'http://stackoverflow.com/questions/12852095/how-does-excels-worksheet-password-protection-work | |
''Sort | |
UL.Worksheets("hash_table").AutoFilter.Sort.SortFields.Clear | |
UL.Worksheets("hash_table").AutoFilter.Sort.SortFields.Add Key:= _ | |
Range("B1:B32769"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _ | |
:=xlSortNormal | |
With UL.Worksheets("hash_table").AutoFilter.Sort | |
.Header = xlYes | |
.MatchCase = False | |
.Orientation = xlTopToBottom | |
.SortMethod = xlPinYin | |
.Apply | |
End With | |
s_t = GetTickCount | |
ETR = 0 | |
''Enable errors resuming | |
On Error Resume Next | |
Do ''Dummy loop to enable early exit from For | |
For i = 2 To 32769 | |
DoEvents | |
''update changes by 1% Calculate ETR | |
If i Mod 300 = 0 Then | |
e_t = GetTickCount | |
If ETR > 0 Then | |
ETR = (ETR + ((32769 - i) / 300 * (s_t - e_t) / 1000)) / 2 | |
Else | |
ETR = (32769 - i) / 300 * (s_t - e_t) / 1000 | |
End If | |
Application.StatusBar = "WB Protection password guessing: " & Format((i / 32769), "0%") & " / Max ETR: " & Format(TimeSerial(0, 0, ETR), "hh:mm:ss") | |
s_t = GetTickCount | |
End If | |
lockedWB.Unprotect UL.Worksheets("hash_table").Cells(i, 1).Value | |
If Not (lockedWB.ProtectWindows Or lockedWB.ProtectStructure) = True Then | |
UnprotectWBook = "Allowable WB Protection password: '" & UL.Worksheets("hash_table").Cells(i, 1).Value & "'" | |
Application.StatusBar = "WB Protection password guessing: " & Format((i / 32769), "0%") & " -> Success!!!" | |
Exit Do | |
End If | |
Next i | |
Loop Until 1 = 1 | |
''Disable errors resuming | |
On Error GoTo 0 | |
''Save WB | |
lockedWB.Close saveChanges:=True | |
Application.StatusBar = "" | |
Application.DisplayAlerts = True | |
Application.ScreenUpdating = True | |
End Function | |
Function UnprotectWSheets(Fname As Variant) As String ''Fname As Variant | |
Application.ScreenUpdating = False | |
Application.StatusBar = "Remove Sheets password..." | |
''Copy Excel file and Rename to ZIP | |
CopyFname = rename_to_zip(copy_excel_file(Fname)) | |
''TMP Folder | |
FileNameFolder = create_TMP_folder | |
'Object for work with ZIP file | |
Set oApp = CreateObject("Shell.Application") | |
''Extract locked sheets | |
For i = 1 To UBound(ProtectedSheets) | |
DoEvents | |
Application.StatusBar = "Sheets Protection / extracting " & "sheet" & ProtectedSheets(i) | |
''Move .xml file to tmp folder | |
oApp.Namespace(FileNameFolder).movehere oApp.Namespace(CopyFname & "\xl\worksheets").items.Item("sheet" & ProtectedSheets(i) & ".xml") | |
Next i | |
''Dim xmlDoc As MSXML2.DOMDocument | |
''Dim objNode As IXMLDOMSelection | |
''Process each locked sheet---------------------- | |
''Create XML object | |
Set xmlDoc = CreateObject("MSXML2.DOMDocument") | |
For i = 1 To UBound(ProtectedSheets) | |
Application.StatusBar = "Sheets Protection / removing protection of " & "sheet" & ProtectedSheets(i) | |
'Load XML file (sheet) | |
xmlDoc.Load FileNameFolder & "\sheet" & ProtectedSheets(i) & ".xml" | |
''Set Node sheetProtection | |
Set objSelecion = xmlDoc.getElementsByTagName("sheetProtection") | |
''Revmove node | |
objSelecion.removeAll | |
''Save changes | |
xmlDoc.Save FileNameFolder & "\sheet" & ProtectedSheets(i) & ".xml" | |
Next i | |
''Overwirte existing sheets in ZIP file------------------------ | |
For i = 1 To UBound(ProtectedSheets) | |
Application.StatusBar = "Sheets Protection / compressing " & "sheet" & ProtectedSheets(i) | |
'' prevent compressing error---- | |
On Error Resume Next | |
Do | |
oApp.Namespace(CopyFname & "\xl\worksheets").CopyHere FileNameFolder & "\sheet" & ProtectedSheets(i) & ".xml" | |
DoEvents | |
Application.Wait (Now + TimeValue("0:00:01")) | |
Loop Until Err.Number = 0 | |
On Error GoTo 0 | |
'Keep script waiting until Compressing is done | |
On Error Resume Next | |
Do Until oApp.Namespace(CopyFname & "\xl\worksheets").items.Item("sheet" & ProtectedSheets(i) & ".xml").Name = CStr("sheet" & ProtectedSheets(i) & ".xml") | |
DoEvents | |
Application.Wait (Now + TimeValue("0:00:01")) | |
Loop | |
On Error GoTo 0 | |
Next i | |
Application.StatusBar = "" | |
UnprotectWSheets = "All the Sheets have been unprotected" | |
Application.ScreenUpdating = True | |
End Function | |
"@ | |
$codeModule_auxiliaryFuncs | Out-File "$($env:TEMP)\auxiliaryFuncs.bas" -Encoding ascii | |
$wb.VBProject.VBComponents.Import("$($env:TEMP)\auxiliaryFuncs.bas") | |
$codeModule_mainFuncs | Out-File "$($env:TEMP)\mainFuncs.bas" -Encoding ascii | |
$wb.VBProject.VBComponents.Import("$($env:TEMP)\mainFuncs.bas") | |
$ws.Columns(2).Hidden = $True | |
$xl.Application.EnableEvents = $True | |
dir $strPath | %{ Write-Output "Deleting $strPath" ; remove-item $strPath -Force } | |
Write-Output "Saving $strPath" | |
$wb.SaveAs($strPath, 52) | |
$wb.Close($False) | |
$xl.Quit() | |
write-output "About to copy $strPath to Desktop, then launch in Excel (sleeping 5 seconds)" | |
# it seems the save is asynchronous | |
Start-Sleep -Seconds 5 | |
$destPath = "$($env:USERPROFILE)\Desktop" | |
Copy-Item $strPath $destPath | |
Invoke-Item "$destPath\$strFile" | |
Pop-Location |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment