- Offizieller Beitrag
Ich muß relativ häufig an Dateien das Erstelldatum ändern, weil dieses bei Speichervorgängen zwischen verschiedenen OS manchmal verändert wird (Datum auf NAS ist z.B. nach Spannungsausfall auf Werkseinstellung - Wird ein Dokument direkt dort abgelegt, bekommt es das falsche Datum).
Bei Dokumenten, die einer Revision unterliegen kommt es natürlich seltsam, wenn in der Fußzeile steht "Rev. 6 vom 05.03.2017" und das Erstelldatum sagt "01.01.2010"
Bisher habe ich dann schnell die Codezeile für FileSetTime händisch befüllt und die Daten korrigiert.
Nun habe ich das mal in eine kleine Oberfläche gepackt.
- Ordner wird ausgewählt (Dateien darin werden in ein Listview geladen mit Anzeige DateCreate, DateModified)
- Dateien mit den Attributen: Hidden, ReadOnly, System werden gleich rot eingefärbt - bei R und S ist das Ändern des Datums sowieso nicht möglich und versteckte Dateien sind sicher nicht umsonst versteckt. Falls diese Dateien doch markiert sind, werden sie vom Tool ignoriert.
- In den Datumsfeldern werden die gewünschten Datumswerte(+ Uhrzeit) gewählt und mit "Datum Setzen" für alle markierten Dateien (selektive Mehrfachauswahl ist möglich) angewendet. Anschliessend wird das Listview neu geladen - die Änderungen sind also sofort sichtbar.
EDIT: [v0.2] Da ich die Attribute sowieso auslese, speichere ich sie zwischen und mit Klick auf eine Datei werden deren Attribute als Tooltip gezeigt.
EDIT: [v0.3]
- NEU: (optional) automatische Übernahme Erstellungsdatum auch als Änderungsdatum
- NEU: Datum aus markierter Datei in Datums-Control übernehmen
- FIXED: Bisher keine Fehlermeldung bei versuchter Änderung einer offenen Datei. Jetzt [FILE-IN-USE] Meldung.
;-- TIME_STAMP 2017-03-30 10:51:41 v 0.3
;-- charset=UTF-8
#include <DateTimeConstants.au3>
#include <EditConstants.au3>
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>
Global $hListView, $iIndexClicked = -1, $aAttrib, $fSameDate = False
_Main()
Func _Main()
Local $hGui = GUICreate('Erstellungs- /Änderungsdatum setzen', 600, 480)
GUICtrlCreateLabel('Verzeichnis', 15, 18, 60)
Local $idPath = GUICtrlCreateInput('', 80, 15, 478, 20, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetBkColor(-1, 0xFFFFFF)
Local $idSelect = GUICtrlCreateButton('...', 563, 14, 22, 22)
GUICtrlCreateLabel('Erstellt', 15, 48, 40)
Local $idDateCreate = GUICtrlCreateDate(StringFormat('%s/%s/%s %s:%s:%s', @Year, @Mon, @MDay, @Hour, @Min, @Sec), 55, 45, 140, 22, $DTS_SHORTDATEFORMAT)
GUICtrlCreateLabel('Geändert', 215, 48, 45)
Local $idDateChange = GUICtrlCreateDate(StringFormat('%s/%s/%s %s:%s:%s', @Year, @Mon, @MDay, @Hour, @Min, @Sec), 265, 45, 140, 22, $DTS_SHORTDATEFORMAT)
Local $sStyle = "dd.MM.yyyy HH:mm:ss"
GUICtrlSendMsg($idDateCreate, $DTM_SETFORMATW, 0, $sStyle)
GUICtrlSendMsg($idDateChange, $DTM_SETFORMATW, 0, $sStyle)
Local $idSet = GUICtrlCreateButton('Datum Setzen', 435, 75, 150, 22)
Local $idCurrentDate = GUICtrlCreateButton('Dateidatum übernehmen', 15, 75, 180, 22)
Local $idSameDate = GUICtrlCreateCheckbox(' Datum Änderung == Erstelldatum', 215, 75)
Local $idListview = GuiCtrlCreateListView('Datei|Erstellt|Geändert', 15, 105, 570, 360, _
BitXOR(BitOR($GUI_SS_DEFAULT_LISTVIEW,$LVS_SHOWSELALWAYS),$LVS_SINGLESEL), _
BitOR($LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT,$LVS_EX_DOUBLEBUFFER))
_GUICtrlListView_SetColumnWidth($idListview, 0, 340)
_GUICtrlListView_SetColumnWidth($idListview, 1, 100)
_GUICtrlListView_SetColumnWidth($idListview, 2, $LVSCW_AUTOSIZE_USEHEADER)
$hListview = GUICtrlGetHandle($idListview)
Local $sSelect, $sDateCreate, $sDateChange, $iIndex
Local $sPattern = '(\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2}):(\d{2})'
Local $sRepl = '$3$2$1$4$5$6'
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; bei Left-Click auf Item werden Attribute als Tooltip gezeigt
GUISetState()
While True
Switch GUIGetMsg()
Case -3
Exit
Case $idSelect
$sSelect = FileSelectFolder('Bitte einen Ordner auswählen', @HomeDrive & '\' & @HomePath)
If $sSelect <> '' Then
GUICtrlSetData($idPath, $sSelect)
If __FillListview($idListview, $sSelect) = 0 Then MsgBox(16, 'Fehler', 'Der gewählte Ordner enthält keine Dateien!')
EndIf
Case $idSet
$sDateCreate = StringRegExpReplace(GUICtrlRead($idDateCreate), $sPattern, $sRepl)
$sDateChange = StringRegExpReplace(GUICtrlRead($idDateChange), $sPattern, $sRepl)
; Plausibilität Create<=Change prüfen (nur wenn beide Daten gesetzt werden)
If Number($sDateCreate) > Number($sDateChange) And (Not $fSameDate) Then
MsgBox(16, 'Fehler', 'Änderungsdatum liegt vor Erstellungsdatum!')
Else
__SetDate(GUICtrlRead($idPath), $idListview, $sDateCreate, $sDateChange)
__FillListview($idListview, GUICtrlRead($idPath))
EndIf
Case $idCurrentDate
Local $aSel = _GUICtrlListView_GetSelectedIndices($idListview, True)
If $aSel[0] = 0 Then
MsgBox(16, 'Fehler', 'Es wurde keine Datei ausgewählt!')
Else
_SetDateCtrl($idDateCreate, _GUICtrlListView_GetItemText($idListview, $aSel[1], 1))
_SetDateCtrl($idDateChange, _GUICtrlListView_GetItemText($idListview, $aSel[1], 2))
EndIf
Case $idSameDate
If BitAND(GUICtrlRead($idSameDate), $GUI_CHECKED) Then
$fSameDate = True
GUICtrlSetState($idDateChange, $GUI_DISABLE)
Else
$fSameDate = False
GUICtrlSetState($idDateChange, $GUI_ENABLE)
EndIf
EndSwitch
WEnd
EndFunc
Func _SetDateCtrl($iID, $sDate)
$sDate = StringRegExpReplace($sDate, '(\d{2})\.(\d{2})\.(\d{4}) (.+)', '$3/$2/$1 $4')
GUICtrlSetData($iID, $sDate)
EndFunc
Func __FillListview($idLV, $sPath)
Local Static $aColor[2] = [0xE5EEFF,0xBCC3FF], $iColWarning = 0xFF93B4
If Not FileExists($sPath) Then Return
Local $aFiles = _FileListToArray($sPath, '*', 1)
If @error Then Return 0
_GUICtrlListView_BeginUpdate($idLV)
_GUICtrlListView_DeleteAllItems($idLV)
Local $sItem, $sPatt = '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})', $sAttrib
Local $aAttr[$aFiles[0]]
For $i = 1 To $aFiles[0]
$sItem = StringFormat('%s|%s|%s', $aFiles[$i], _
StringRegExpReplace(FileGetTime($sPath & '\' & $aFiles[$i], 1, 1), $sPatt, '$3.$2.$1 $4:$5:$6'), _
StringRegExpReplace(FileGetTime($sPath & '\' & $aFiles[$i], 0, 1), $sPatt, '$3.$2.$1 $4:$5:$6'))
GUICtrlCreateListViewItem($sItem, $idLV)
$sAttrib = FileGetAttrib($sPath & '\' & $aFiles[$i])
$aAttr[$i-1] = $sAttrib
If StringInStr($sAttrib, 'H') Or StringInStr($sAttrib, 'R') Or StringInStr($sAttrib, 'S') Then
GUICtrlSetBkColor(-1, $iColWarning)
Else
GUICtrlSetBkColor(-1, $aColor[Mod($i,2)])
EndIf
Next
$aAttrib = $aAttr
_GUICtrlListView_EndUpdate($idLV)
Return $aFiles[0]
EndFunc
Func __SetDate($sFolder, $idLV, $sCreate, $sChange)
If $sFolder = '' Then Return
Local $aSel = _GUICtrlListView_GetSelectedIndices($idLV, True)
If $aSel[0] = 0 Then Return MsgBox(16, 'Fehler', 'Es wurde keine Datei ausgewählt!')
Local $sFile, $sAttrib, $sErr = '', $iOK
For $i = 1 To $aSel[0]
$sFile = $sFolder & '\' & _GUICtrlListView_GetItemText($idLV, $aSel[$i])
$sAttrib = FileGetAttrib($sFile)
If StringInStr($sAttrib, 'R') Then
$sErr &= '[READONLY] ' & $sFile & @CRLF
ContinueLoop
ElseIf StringInStr($sAttrib, 'S') Then
$sErr &= '[SYSTEM] ' & $sFile & @CRLF
ContinueLoop
ElseIf StringInStr($sAttrib, 'H') Then
$sErr &= '[HIDDEN] ' & $sFile & @CRLF
ContinueLoop
EndIf
$iOK = 0
$iOK += FileSetTime($sFile, $sCreate, 1)
$iOK += FileSetTime($sFile, ($fSameDate ? $sCreate : $sChange), 0)
If $iOK < 2 Then $sErr &= '[FILE-IN-USE] ' & $sFile & @CRLF
Next
If $sErr <> '' Then Return MsgBox(16, 'Fehler', 'Folgende Dateien wurden nicht bearbeitet:' & @CRLF & $sErr)
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
If HWnd(DllStructGetData($tNMHDR, "hWndFrom")) = $hListView And _
DllStructGetData($tNMHDR, "Code") = $NM_CLICK Then
Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndexClicked = DllStructGetData($tInfo, "Index")
AdlibRegister('__TipAttrib')
EndIf
Return $GUI_RUNDEFMSG
EndFunc
Func __TipAttrib()
If $iIndexClicked = -1 Then Return
AdlibUnRegister('__TipAttrib')
Local $sText = $aAttrib[$iIndexClicked]
_ToolTipMouseExit($sText, 1700, -1, -1, 'Attribute', 1, 1)
$iIndexClicked = -1
EndFunc
Func _ToolTipMouseExit($TEXT, $TIME=-1, $x=-1, $y=-1, $TITLE='', $ICON=0, $OPT='')
; Standard ToolTip, ergänzt um Schließen nach Zeit oder bei Mausbewegung
If $TIME = -1 Then $TIME = 3000
Local $start = TimerInit()
Local $pos, $pos0 = MouseGetPos()
If ($x = -1) Or ($y = -1) Then
ToolTip($TEXT, $pos0[0], $pos0[1], $TITLE, $ICON, $OPT)
Else
ToolTip($TEXT, $x, $y, $TITLE, $ICON, $OPT)
EndIf
Do
Sleep(50)
$pos = MouseGetPos()
Until (TimerDiff($start) > $TIME) Or _
(Abs($pos[0] - $pos0[0]) > 10 Or _
Abs($pos[1] - $pos0[1]) > 10)
ToolTip('')
EndFunc ;==>_ToolTipMouseExit
Alles anzeigen