Hallo zusammen,
ich bin ganz neu hier im Forum und brauche direkt mal eure Hilfe / Unterstützung:
Ich schreibe gerade ein kleines Skript für meine Eltern, dass die wichtigsten Ordner und Dateien auf ihrem Computer auf einer externen Festplatte sichert. Das ganze funktioniert soweit schon ganz gut und läuft wie folgt ab:
- Beim ersten Start des Programms (das sich auf der externen Festplatte befindet) wird ein Ordner "Backups" mit einem Unterordner "Computername", im Skriptverzeichnis, angelegt.
- Anschließend wird eine settings.ini für diesen PC erzeugt, die ein paar Informationen enthält.
- Dann wird eine paths.txt erzeugt, die erstmal leer ist aber später pro Zeile einen Pfad enthalten soll, der dann mitgesichert wird.
- Wenn man möchte kann man das Backup zippen lassen, dann werden halt alle Dateien in eine .zip gepackt und der normale Sicherungsordner wird wieder gelöscht.
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Bilder\logo.ico
#AutoIt3Wrapper_Outfile=DataSaver 1.0.Exe
#AutoIt3Wrapper_Res_Fileversion=1.0
#AutoIt3Wrapper_Res_Language=1031
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <GuiStatusBar.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <File.au3>
#include <Array.au3>
#include <zip.au3>
;Hauptfenster
$formMain = GUICreate("DataSaver 1.0", 307, 124, -1, -1)
$menuMainItem1 = GUICtrlCreateMenu("&Datei")
$menuMainItem1Item1 = GUICtrlCreateMenuItem("Zu sichernde Objekte auswählen", $menuMainItem1)
$menuMainItem2 = GUICtrlCreateMenu("&Optionen")
$menuMainItem2Item1 = GUICtrlCreateMenuItem("Komprimiere das Backup (.zip)", $menuMainItem2)
GUICtrlSetState(-1, $GUI_CHECKED)
$menuMainItem3 = GUICtrlCreateMenu("?")
$statusbarMain = _GUICtrlStatusBar_Create($formMain)
Dim $statusbarMain_PartsWidth[1] = [-1]
_GUICtrlStatusBar_SetParts($statusbarMain, $statusbarMain_PartsWidth)
_GUICtrlStatusBar_SetText($statusbarMain, "", 0)
$iconArchiv = GUICtrlCreateIcon("F:\OneDrive\Dokumente\Projekte\DataSaverX\Bilder\archiv.ico", -1, 232, 10, 64, 64)
$iconSpeichern = GUICtrlCreateIcon("F:\OneDrive\Dokumente\Projekte\DataSaverX\Bilder\speichern.ico", -1, 10, 10, 64, 64)
$iconINI = GUICtrlCreateIcon("F:\OneDrive\Dokumente\Projekte\DataSaverX\Bilder\ini.ico", -1, 158, 10, 64, 64)
$iconTXT = GUICtrlCreateIcon("F:\OneDrive\Dokumente\Projekte\DataSaverX\Bilder\txt.ico", -1, 84, 10, 64, 64)
;Globale Variablen
Global $pfadSicherungsordnerMain = @ScriptDir & "\Backups\" & @ComputerName
Global $pfadINI = $pfadSicherungsordnerMain & "\settings.ini"
Global $pfadTXT = $pfadSicherungsordnerMain & "\paths.txt"
Global $ordner
;Start des Programms
DirCreate($pfadSicherungsordnerMain)
IniWrite($pfadINI, "Allgemein", "Computername", @ComputerName)
If Not FileExists($pfadTXT) Then
FileWrite($pfadTXT, "")
MsgBox(64, "Information", "Es wurde eine neue paths.txt für diesen PC angelegt.")
EndIf
If IniRead($pfadINI, "Einstellungen", "ZIP", "no") = "yes" Then
GUICtrlSetState($menuMainItem2Item1, $GUI_CHECKED)
Else
GUICtrlSetState($menuMainItem2Item1, $GUI_UNCHECKED)
EndIf
_mainGUI(1)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $iconSpeichern
GUICtrlSetPos($iconSpeichern, 26, 26, 32, 32)
Sleep(150)
GUICtrlSetPos($iconSpeichern, 10, 10, 64, 64)
If Not _FileReadToArray($pfadTXT, $ordner) Then
MsgBox(16, "Fehler", "Du musst erst Ordner eintragen die übertragen werden sollen!")
ShellExecute($pfadTXT)
Else
IniWrite($pfadINI, "Allgemein", "Sicherungen", IniRead($pfadINI, "Allgemein", "Sicherungen", "0") + 1)
$time = @YEAR & "-" & @MON & "-" & @MDAY & "_" & @HOUR & "-" & @MIN
IniWrite($pfadINI, "Letzte Sicherung", "Zeitpunkt", $time)
$pfadSicherungsordnerHeute = $pfadSicherungsordnerMain & "\" & $time
DirCreate($pfadSicherungsordnerHeute)
For $x = 1 To $ordner[0]
$pfadSicherungsordnerHeuteOrdner = $pfadSicherungsordnerHeute
$einzelordner = StringSplit($ordner[$x], "\")
$einzelordner[1] = StringTrimRight($einzelordner[1], 1)
For $y = 1 To $einzelordner[0]
$pfadSicherungsordnerHeuteOrdner = $pfadSicherungsordnerHeuteOrdner & "\" & $einzelordner[$y]
Next
_GUICtrlStatusBar_SetText($statusbarMain, "Kopiere " & $ordner[$x], 0)
$pid = Run("cmd /c """ & 'robocopy ' & '"' & $ordner[$x] & '" "' & $pfadSicherungsordnerHeuteOrdner & '" /MIR' & """", "", @SW_HIDE, 6)
Next
Sleep(500)
If IniRead($pfadINI, "Einstellungen", "ZIP", "no") = "yes" Then
_GUICtrlStatusBar_SetText($statusbarMain, "Backup wird gezippt...", 0)
$zip = _Zip_Create($pfadSicherungsordnerHeute & ".zip")
_Zip_AddFolderContents($zip, $pfadSicherungsordnerHeute)
DirRemove($pfadSicherungsordnerHeute, 1)
Sleep(500)
ShellExecute($zip)
Else
ShellExecute($pfadSicherungsordnerHeute)
EndIf
_GUICtrlStatusBar_SetText($statusbarMain, "Backup wurde erfolgreich beendet.", 0)
EndIf
;Zeigt das Array an: _ArrayDisplay($ordner)
Case $iconTXT
GUICtrlSetPos($iconTXT, 100, 26, 32, 32)
Sleep(150)
GUICtrlSetPos($iconTXT, 84, 10, 64, 64)
ShellExecute($pfadTXT)
Case $iconINI
GUICtrlSetPos($iconINI, 174, 26, 32, 32)
Sleep(150)
GUICtrlSetPos($iconINI, 158, 10, 64, 64)
ShellExecute($pfadINI)
Case $iconArchiv
GUICtrlSetPos($iconArchiv, 248, 26, 32, 32)
Sleep(150)
GUICtrlSetPos($iconArchiv, 232, 10, 64, 64)
ShellExecute($pfadSicherungsordnerMain)
Case $menuMainItem1Item1
;FileTree
Case $menuMainItem2Item1
If BitAND(GUICtrlRead($menuMainItem2Item1), $GUI_CHECKED) = $GUI_CHECKED Then
GUICtrlSetState($menuMainItem2Item1, $GUI_UNCHECKED)
IniWrite($pfadINI, "Einstellungen", "ZIP", "no")
Else
GUICtrlSetState($menuMainItem2Item1, $GUI_CHECKED)
IniWrite($pfadINI, "Einstellungen", "ZIP", "yes")
EndIf
EndSwitch
WEnd
Func _mainGUI($visibility)
If $visibility Then
GUISetState(@SW_SHOW, $formMain)
Else
GUISetState(@SW_HIDE, $formMain)
EndIf
EndFunc
Alles anzeigen
Das ganze ist natürlich noch nicht 100% optimal, dient mir aber als Einsteigerprojekt ! Ich habe auch vor es stetig weiterzuentwickeln.
Nun möchte ich noch einen FileTree anzeigen lassen, wenn man unter "Datei -> Zu sichernde Objekte auswählen" klickt. Dieser soll alle Ordner und Dateien anzeigen, mit "+" bzw. "-" und einer Checkbox vor dem Datei-/Ordnernamen.
Auch dafür habe ich schon ein Skript gefunden, allerdings hapert es jetzt daran auszulesen welche Einträge alle markiert wurden und diese dann in die paths.txt zu schreiben.
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiTreeView.au3>
#include <StructureConstants.au3>
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>
Opt('MustDeclareVars', 1)
Global $hGui = GUICreate('FileExplorer', 600, 600)
Global Const $Delim = '\', $Delim1 = '|'
Global $hTreeview = GUICtrlCreateTreeView(5, 5, 590, 500, BitOR($TVS_CHECKBOXES, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT))
Global $hWndTreeview = GUICtrlGetHandle($hTreeview)
Global $hOk = GUICtrlCreateButton('Ok', 240, 510, 60, 22)
Global $hCancel = GUICtrlCreateButton('Cancel', 320, 510, 60, 22)
Global $hImage = _GUIImageList_Create(16, 16, 5, 1)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 3) ; Verzeichnis-Icon
_GUIImageList_AddIcon($hImage, 'shell32.dll', 110) ; Verzeichnis-Icon mit Haken
_GUIImageList_AddIcon($hImage, 'shell32.dll', 1) ; Datei-Icon
_GUIImageList_AddIcon($hImage, 'shell32.dll', 5) ; Diskette
_GUIImageList_AddIcon($hImage, 'shell32.dll', 7) ; Wechseldatenträger
_GUIImageList_AddIcon($hImage, 'shell32.dll', 8) ; Festplatte
_GUIImageList_AddIcon($hImage, 'shell32.dll', 11) ; CDROM
_GUIImageList_AddIcon($hImage, 'shell32.dll', 12) ; Netzwerklaufwerk
_GUIImageList_AddIcon($hImage, 'shell32.dll', 53) ; Unbekannt
_GUICtrlTreeView_SetNormalImageList($hTreeview, $hImage)
GUISetState()
GUICtrlSetStyle($hTreeview, Default, BitOR($WS_EX_COMPOSITED, $WS_EX_CLIENTEDGE))
If ToolTip('Please wait...', Default, Default, 'Read Directory', 1) Then Local $aDrives = DriveGetDrive('ALL'), $iLWindex, $hRoot
For $i = 1 To $aDrives[0]
$iLWindex = 0
Switch DriveGetType($aDrives[$i])
Case 'Fixed'
$iLWindex = 5
Case 'CDROM'
$iLWindex = 6
Case 'RAMDisk'
$iLWindex = 7
Case 'Removable'
$iLWindex = 4
If StringLeft($aDrives[$i], 2) = 'a:' Or StringLeft($aDrives[$i], 2) = 'b:' Then $iLWindex = 3
Case Else
$iLWindex = 8
EndSwitch
$hRoot = _GUICtrlTreeView_Add($hTreeview, $hTreeview, StringUpper($aDrives[$i]), $iLWindex, $iLWindex)
If DriveStatus($aDrives[$i]) <> 'READY' Then ContinueLoop
If _GUICtrlTreeView_BeginUpdate($hTreeview) And _GUICtrlTreeView_FileExplorer($hTreeview, $hRoot, $aDrives[$i]) Then _GUICtrlTreeView_EndUpdate($hTreeview)
Next
ToolTip('')
GUIRegisterMsg($WM_NOTIFY, '_WM_NOTIFY')
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $hCancel
Exit
Case $hOk
MsgBox(0, 'Selected Path/File', StringReplace(_GUICtrlTreeView_GetTree($hTreeview, _GUICtrlTreeView_GetSelection($hTreeview)), $Delim1, $Delim))
Case $hTreeview
If _GUICtrlTreeView_GetChecked($hTreeview, _GUICtrlTreeView_GetSelection($hTreeview)) Then
MsgBox(0, "", _GUICtrlTreeView_GetSelection($hTreeview) & " wurde gecheckt.")
Else
MsgBox(0, "", _GUICtrlTreeView_GetSelection($hTreeview) & " wurde ungecheckt.")
EndIf
EndSwitch
WEnd
Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hChild, $hITEM, $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam)
If DllStructGetData($tNMTREEVIEW, 'hWndFrom') = $hWndTreeview Then
Switch DllStructGetData($tNMTREEVIEW, 'Code')
Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
Switch DllStructGetData($tNMTREEVIEW, 'Action')
Case $TVE_EXPAND
If ToolTip('Please wait...', Default, Default, 'Read Directory', 1) Then $hITEM = DllStructGetData($tNMTREEVIEW, 'NewhItem')
If _GUICtrlTreeView_GetExpanded($hTreeview, $hITEM) Then Return $GUI_RUNDEFMSG
$hChild = _GUICtrlTreeView_GetFirstChild($hTreeview, $hITEM)
If Not $hChild Then Return $GUI_RUNDEFMSG
If _GUICtrlTreeView_BeginUpdate($hTreeview) Then _GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
_GUICtrlTreeView_FileExplorer($hTreeview, $hChild, StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), $Delim1, $Delim))
Do
$hChild = _GUICtrlTreeView_GetNextChild($hTreeview, $hChild)
If Not $hChild Then ExitLoop
_GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
_GUICtrlTreeView_FileExplorer($hTreeview, $hChild, StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), $Delim1, $Delim))
Until False
If _GUICtrlTreeView_EndUpdate($hTreeview) Then ToolTip('')
EndSwitch
EndSwitch
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>_WM_NOTIFY
Func _GUICtrlTreeView_FileExplorer($hTreeview, $hITEM, $sPath)
Local $sFileList, $sFolderList, $aDirList, $hSearch, $sFile
Local $iHidden = RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced', 'Hidden') - 1
Local $iSuperHidden = Not RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced', 'ShowSuperHidden')
$hSearch = FileFindFirstFile($sPath & $Delim & '*')
If $hSearch = -1 Then Return True
Do
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
Switch @extended
Case False
If $iHidden And StringInStr(FileGetAttrib($sPath & $Delim & $sFile), 'H') Then ContinueLoop
If $iSuperHidden And StringInStr(FileGetAttrib($sPath & $Delim & $sFile), 'S') Then ContinueLoop
$sFileList &= $sFile & $Delim1
Case True
If _IsReparsePoint($sPath & $Delim & $sFile) Then ContinueLoop
$sFolderList &= $sFile & $Delim1
EndSwitch
Until False
FileClose($hSearch)
If $sFolderList & $sFileList = '' Then Return True
$aDirList = StringSplit(StringTrimRight($sFolderList & $sFileList, 1), $Delim1, 2)
For $sFile In $aDirList
If StringInStr(FileGetAttrib($sPath & $Delim & $sFile), 'D') Then
_GUICtrlTreeView_AddChild($hTreeview, $hITEM, $sFile, 0, 1)
Else
_GUICtrlTreeView_AddChild($hTreeview, $hITEM, $sFile, 2, 2)
EndIf
Next
Return True
EndFunc ;==>_GUICtrlTreeView_FileExplorer
Func _IsReparsePoint($FLS) ; progandy
Static $K32 = DllOpen('kernel32.dll')
Dim $DA = DllCall($K32, 'dword', 'GetFileAttributesW', 'wstr', $FLS)
If @error Then Return SetError(1, @error, False)
Return BitAND($DA[0], 1024) = 1024
EndFunc ;==>_IsReparsePoint
Alles anzeigen
Wenn das funktioniert wäre es natürlich auch schön, wenn man beim Starten des TreeViews sieht welche Ordner schon in der paths.txt stehen, sprich dass diese Elemente bereits angehackt werden. Das ist aber nicht unbedingt notwendig!
Ich bin dankbar für jede Hilfe!
Danke,
Sascha