Kennwort geschützte Dokumente nicht öffnen

  • Hi, ich habe noch ein kleines Problem mit einem Script.
    Und zwar gibt es Probleme bei Worddokumenten die mit sehr alten Vorlagen erstellt worden sind, wenn sie aus externen Anwendungen gestartet werden. (MS Sicherheitseinstellungen in 2010 sind "Schuld", nur wollte ich diese nicht herunterschrauben). Gelöst habe ich es schon. Nur werden auch Passwortgeschützte Dateien geöffnet (was er natürlich Aufgrund des Passwortes nicht kann) und das ganze Script steht. Da es knapp 30k Worddokumente sind wollte ich nicht die ganze Zeit davor sitzen und Abbrechen klicken ;). Hat Jemand eine Idee wie man dies lösen kann? Habe schon mit _WordDocPropertyGet($oDoc, 6) versucht die Passwortgeschützten auszuschließen (leider erfolglos, da es keinen eindeutigen Rückgabewert gab).

    Spoiler anzeigen
    [autoit]

    #RequireAdmin
    Opt("TrayAutoPause",0)
    Opt("TrayIconHide",1)
    #include <Word.au3>
    #include <File.au3>
    #include <GUIConstantsEx.au3>
    #include <Timers.au3>
    Local $pathall = ""
    Local $aDocFormate[5] = ["*.doc", "*.docx", "*.dot", "*.dotx", "*.dotm"]
    $hGui = GUICreate("Word Repair", 526, 78, 192, 114)
    $cPath = GUICtrlCreateInput("C:\Dokumente", 8, 8, 505, 21)
    $cStarten = GUICtrlCreateButton("Starten", 8, 40, 75, 25)
    GUISetState(@SW_SHOW, $hGui)
    _WordErrorHandlerRegister("MyErrFunc")
    _WordErrorNotify(1)
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case -3
    Exit
    Case $cStarten
    $sPath = GUICtrlRead($cPath)
    If FileExists($sPath) Then
    If StringInStr(StringRight($sPath,1),"\") = 0 Then $sPath &= "\"
    $aPaths = _ReFileListToString($sPath)
    $starttime = _Timer_Init()
    GUISetState(@SW_HIDE, $hGui)
    GUICtrlSetState($cStarten, $GUI_DISABLE)
    $sProtokoll = @ScriptDir & "\Protokoll_" & @MDAY & "." & @MON & "." & @YEAR & "_" & @HOUR & "-" & @MIN & ".log"
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    $aVersion = _Word_VersionInfo()
    FileWrite($sProtokoll, "Office Version: " & $aVersion[0] & $aVersion[1] & $aVersion[2] & @CRLF)
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    $oWordApp = _WordCreate("", 0, 0)
    For $iPaths = 0 To UBound($aPaths) - 1
    FileWrite($sProtokoll, "-------------------------------------------------------" & @CRLF)
    FileWrite($sProtokoll, "Pfad: " & $aPaths[$iPaths] & @CRLF)
    FileWrite($sProtokoll, "-------------------------------------------------------" & @CRLF)
    For $iFormat = 0 To UBound($aDocFormate) - 1
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    $aDateien = _FileListToArray($aPaths[$iPaths], $aDocFormate[$iFormat], 1)
    If UBound($aDateien) = 0 Then
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    FileWrite($sProtokoll, "Keine " & $aDocFormate[$iFormat] & " Dokumente gefunden" & @CRLF)
    Else
    ProgressOn($aDocFormate[$iFormat], "", "0 von " & $aDateien[0], Default, 0, 1)
    For $i = 1 To $aDateien[0]
    If StringInStr(FileGetAttrib($aPaths[$iPaths] & $aDateien[$i]),"T") = 0 Then
    ConsoleWrite($aPaths[$iPaths] & $aDateien[$i] & @CRLF)
    FileSetAttrib($aPaths[$iPaths] & $aDateien[$i],"-R")
    ProgressSet($i * 100 / $aDateien[0], $i & " von " & $aDateien[0], $aDateien[$i])
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    FileWrite($sProtokoll, "Dokument: " & $aDateien[$i] & @CRLF)
    $oDoc = _WordDocOpen($oWordApp, $aPaths[$iPaths] & $aDateien[$i])
    If @error = 1 Then
    FileWrite($sProtokoll, "Datei konnte nicht geöffnet werden" & @CRLF)
    Else
    FileWrite($sProtokoll, "Alte Vorlage: " & _WordDocPropertyGet($oDoc, 6) & @CRLF)
    $oDoc.AttachedTemplate = ""
    FileWrite($sProtokoll, "Neue Vorlage: " & _WordDocPropertyGet($oDoc, 6) & @CRLF)
    FileWrite($sProtokoll, "Sicherheit: " & _WordDocPropertyGet($oDoc, 17) & @CRLF)
    _WordDocSaveAs($oDoc, $aPaths[$iPaths] & $aDateien[$i])
    EndIf
    _WordDocClose($oDoc)
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    FileWrite($sProtokoll, "Anzahl " & $aDocFormate[$iFormat] & " Dateien: " & $aDateien[0] & " Dauer bisher: " & Round(_Timer_Diff($starttime) / 60000, 2) & " Minuten" & @CRLF)
    FileWrite($sProtokoll, "=======================================================" & @CRLF)
    ProgressOff()
    EndIf
    Next
    Next
    _WordQuit($oWordApp)
    GUISetState(@SW_SHOW, $hGui)
    MsgBox(0, "", "Fertig")
    GUICtrlSetState($cStarten, $GUI_ENABLE)
    ShellExecute($sProtokoll)
    Else
    MsgBox(16, "", GUICtrlRead($cPath) & @CRLF & "Pfad konnte nicht gefunden werden")
    EndIf
    EndSwitch
    WEnd
    _WordErrorHandlerDeRegister()
    _WordErrorNotify(0)
    Func _ReFileListToString($path) ;by Oscar (Autoit.de)
    Local $count, $Files
    Local $dFileList = _FileListToArray($path, '*', 2)
    $pathall &= $path & "|"
    If IsArray($dFileList) Then
    For $i = 1 To $dFileList[0]
    Local $hSearch, $sFile
    $hSearch = FileFindFirstFile($path & $dFileList[$i] & "\" & '*.*')
    If $hSearch <> -1 Then
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then
    SetError(0)
    ExitLoop
    EndIf
    If StringInStr(FileGetAttrib($path & $dFileList[$i] & "\" & $sFile), "D") <> 0 Then ContinueLoop
    $count += 1
    $Files &= $path & $dFileList[$i] & "\" & $sFile & '|'
    WEnd
    FileClose($hSearch)
    EndIf
    _ReFileListToString($path & $dFileList[$i] & '\')
    Next
    EndIf
    Return StringSplit(StringTrimRight($pathall, 1), "|", 2)
    EndFunc ;==>_ReFileListToString
    Func MyErrFunc()
    ; Wichtig: Die Fehler-Objektvariable muss $oWordErrorHandler genannt werden!
    $ErrorDescription = StringStripWS($oWordErrorHandler.description, 2)
    FileWrite($sProtokoll, "COM-Fehler: " & $ErrorDescription & @CRLF)
    SetError(1)
    Return
    EndFunc ;==>MyErrFunc

    [/autoit]

    21 is only half the truth.

    Einmal editiert, zuletzt von Mahagon (30. November 2010 um 22:22)

  • Mir würden jetzt spontan drei Dinge einfallen:
    - etwas suchen, dass eine Fehlermeldung/@error zurückgibt; vielleicht beim öffnen?
    - abfragen, welches Fenster aktiv ist (Wenn Wintitle = Passwort eingeben oder so ähnlich dann einen controlklick auf nein/abbrechen)
    - oder die Zeit stoppen?

  • Da das Script erst fortfährt sobald man auf OK oder Abbrechen beim Passwortdialog klickt ist das ziemlich schwierig ;)
    deswegen muss ich es wohl irgendwie über eine Methode, die feststellt, ob das ganze passwortgeschützt ist.

    21 is only half the truth.

    • Offizieller Beitrag

    Die Lösung ist so einfach, dass man kaum drauf kommt:

    [autoit]

    #include <Word.au3>

    [/autoit][autoit][/autoit][autoit]

    $oWord = ObjCreate("Word.Application")
    $oWord.Visible = 1

    [/autoit][autoit][/autoit][autoit]

    $oDoc = _WordDocOpen($oWord, 'C:\Pfad\test.doc', 0, 0, 0, 0, 0, "Passwort")

    [/autoit]


    Einfach alle Dateien mit irgendeinem Passwort öffnen. Die DOC ohne Passwort werden dann geöffnet. Die mit werden nicht geöffnet - es erscheint aber keine DialogBox!

  • Habe ich auch gerade feststellen müssen, als ich einfach mal "None" als Passwort eingegeben habe.,.. oh man.

    Naja vielen Dank :)

    Hier noch einmal das vollständige Script, falls es jemand braucht:

    Spoiler anzeigen
    [autoit]

    #RequireAdmin
    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.3.6.1
    Author: Daniel Jacobs

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    löscht den Vorlagepfad (dieser verlangsamt oft den start in neuen Umgebungen)
    Speichert die Dokumente in der aktuellen Office Version erneut, um Kompatibilitätsprobleme bei älteren Dokumenten beheben
    (Beispielsweise, wenn die Dokumente aus einer Office 97 *.dot erstellt worden sind)

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    Opt("TrayAutoPause", 0)
    Opt("TrayIconHide", 1)
    #include <Word.au3>
    #include <File.au3>
    #include <GUIConstantsEx.au3>
    #include <Timers.au3>
    Local $pathall = ""
    Local $iAllFilecounter = 0
    Local $iCurrentFile = 0
    Local $endtimeopendoc = 0
    Local $aDocFormate[2] = ["*.doc", "*.dot"]
    $hGui = GUICreate("Word Repair", 526, 78, 192, 114)
    $cPath = GUICtrlCreateInput("C:\", 8, 8, 505, 21)
    $cStarten = GUICtrlCreateButton("Starten", 8, 40, 75, 25)
    GUISetState(@SW_SHOW, $hGui)
    _WordErrorHandlerRegister("MyErrFunc")
    _WordErrorNotify(True)
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case -3
    Exit
    Case $cStarten
    $sPath = GUICtrlRead($cPath)
    If FileExists($sPath) Then
    If StringInStr(StringRight($sPath, 1), "\") = 0 Then $sPath &= "\"
    $starttime = _Timer_Init()
    GUISetState(@SW_HIDE, $hGui)
    GUICtrlSetState($cStarten, $GUI_DISABLE)
    ProgressOn("Worddateien in " & StringTrimRight($sPath, 1) & " werden repariert", $sPath, "Ordner werden durchsucht", Default, 0, 16)
    $aPaths = _ReFileListToString($sPath)
    ToolTip("")
    $sProtokoll = @ScriptDir & "\Protokoll_" & @MDAY & "." & @MON & "." & @YEAR & "_" & @HOUR & "-" & @MIN & "-" & @SEC & "-" & @MSEC & ".log"
    $aVersion = _Word_VersionInfo()
    FileWrite($sProtokoll, "Office Version: " & $aVersion[0] & $aVersion[1] & $aVersion[2] & @CRLF)
    $oWordApp = _WordCreate("", 0, 0)
    For $iPaths = 0 To UBound($aPaths) - 1
    For $iFormat = 0 To UBound($aDocFormate) - 1
    $aDateien = _FileListToArray($aPaths[$iPaths], $aDocFormate[$iFormat], 1)
    If UBound($aDateien) <> 0 Then
    FileWrite($sProtokoll, "-------------------------------------------------------" & @CRLF)
    FileWrite($sProtokoll, " " & @CRLF)
    FileWrite($sProtokoll, "Pfad: " & $aPaths[$iPaths] & @CRLF)
    FileWrite($sProtokoll, " " & @CRLF)
    FileWrite($sProtokoll, " " & @CRLF)
    For $i = 1 To $aDateien[0]
    If StringInStr(FileGetAttrib($aPaths[$iPaths] & $aDateien[$i]), "T") = 0 And StringLeft($aDateien[$i],2) <> "~$" Then ;Temporäre Dateien werden ausgeschlossen
    FileSetAttrib($aPaths[$iPaths] & $aDateien[$i], "-R") ;Schreibschutz (falls vorhanden) wird entfernt)
    FileWrite($sProtokoll, "Dokument: " & @TAB & @TAB & $aDateien[$i] & @CRLF)
    $iCurrentFile += 1
    ProgressSet($iCurrentFile * 100 / $iAllFilecounter, StringTrimLeft($aPaths[$iPaths], StringLen($sPath) - 1) & $aDateien[$i] & @CRLF _
    & "~" & $endtimeopendoc & " Minuten verbleibend.", $iCurrentFile & " von " & $iAllFilecounter & " verarbeitet")
    $oWordApp.Visible = False ; Setzt das Fenster auf Unsichtbar, falls es durch irgendwelche Einflüsse sichtbar wurde
    $starttimeopendoc = _Timer_Init()
    $oDoc = _WordDocOpen($oWordApp, $aPaths[$iPaths] & $aDateien[$i], 0, 0, 0, 0, 0, "None") ;Das Passwort "None" verhindert den Passwortdialog
    If Not @error Then
    If $aDocFormate[$iFormat] = "*.doc" Then
    FileWrite($sProtokoll, "Alte Vorlage: " & @TAB & $oDoc.AttachedTemplate.FullName & @CRLF)
    $oDoc.AttachedTemplate = "";Vorlage wird entfernt
    FileWrite($sProtokoll, "Neue Vorlage: " & @TAB & $oDoc.AttachedTemplate.FullName & @CRLF)
    EndIf
    $oDoc.SaveAs($aPaths[$iPaths] & $aDateien[$i]);Wird erneut gespeichert
    _WordDocClose($oDoc)
    $endtimeopendoc = Round(_Timer_Diff($starttimeopendoc) * ($iAllFilecounter - $iCurrentFile) / 60000, 2)
    EndIf
    Else
    $iCurrentFile += 1
    EndIf
    If $iFormat <> 1 Then FileWrite($sProtokoll, " " & @CRLF)
    Next
    FileWrite($sProtokoll, " " & @CRLF)
    FileWrite($sProtokoll, "Anzahl " & $aDocFormate[$iFormat] & " Dateien: " & $aDateien[0] & " Dauer bisher: " & Round(_Timer_Diff($starttime) / 60000, 2) & " Minuten" & @CRLF)
    $aDateien = _FileListToArray($aPaths[$iPaths], "*.wbk", 1);entfernen der Sicherungsdateien
    If UBound($aDateien) <> 0 Then
    For $i = 1 To $aDateien[0]
    ProgressSet($i * 100 / $aDateien[0], $i & " von " & $aDateien[0] & " Sicherungsdateien entfernt", $aDateien[$i])
    FileDelete($aPaths[$iPaths] & $aDateien[$i])
    Next
    EndIf
    EndIf
    Next
    Next
    FileWrite($sProtokoll, "-------------------------------------------------------" & @CRLF)
    FileWrite($sProtokoll, "-------------------------------------------------------" & @CRLF)
    FileWrite($sProtokoll,$iAllFilecounter & " Dateien von " & $iCurrentFile & " Dateien sind in " & Round(_Timer_Diff($starttime) / 60000, 2) & " Minuten bearbeitet worden.")
    ProgressOff()
    _WordQuit($oWordApp)
    GUISetState(@SW_SHOW, $hGui)
    MsgBox(0, "", "Fertig")
    GUICtrlSetState($cStarten, $GUI_ENABLE)
    ShellExecute($sProtokoll)
    Else
    MsgBox(16, "", GUICtrlRead($cPath) & @CRLF & "Pfad konnte nicht gefunden werden")
    EndIf
    EndSwitch
    WEnd
    _WordErrorHandlerDeRegister()
    _WordErrorNotify(False)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _ReFileListToString($path) ;by Oscar (Autoit.de)
    Local $count, $Files
    Local $dFileList = _FileListToArray($path, '*', 2)
    For $i = 0 To UBound($aDocFormate) - 1
    $aDateien = _FileListToArray($path, $aDocFormate[$i], 1)
    If UBound($aDateien) <> 0 Then $iAllFilecounter += $aDateien[0]
    ProgressSet(0, $iAllFilecounter & " Word Dokumente gefunden.", $path)
    Next
    $pathall &= $path & "|"
    If IsArray($dFileList) Then
    For $i = 1 To $dFileList[0]
    Local $hSearch, $sFile
    $hSearch = FileFindFirstFile($path & $dFileList[$i] & "\" & '*.*')
    If $hSearch <> -1 Then
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then
    SetError(0)
    ExitLoop
    EndIf
    If StringInStr(FileGetAttrib($path & $dFileList[$i] & "\" & $sFile), "D") <> 0 Then ContinueLoop
    $count += 1
    $Files &= $path & $dFileList[$i] & "\" & $sFile & '|'
    WEnd
    FileClose($hSearch)
    EndIf
    _ReFileListToString($path & $dFileList[$i] & '\')
    Next
    EndIf
    Return StringSplit(StringTrimRight($pathall, 1), "|", 2)
    EndFunc ;==>_ReFileListToString
    Func MyErrFunc()
    ; Wichtig: Die Fehler-Objektvariable muss $oWordErrorHandler genannt werden!
    $ErrorDescription = StringStripWS($oWordErrorHandler.description, 2)
    FileWrite($sProtokoll, "COM-Fehler: " & $ErrorDescription & @CRLF)
    SetError(1)
    Return
    EndFunc ;==>MyErrFunc

    [/autoit]

    21 is only half the truth.

    2 Mal editiert, zuletzt von Mahagon (14. Februar 2011 um 13:25)