Автор: AZJIO
Дата сообщения: 03.07.2010 04:19
Утилита - [more=Поиск дубликатов]
Код: ; @AZJIO 2010.07.09
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_OutFile=Search_duplicates.exe
#AutoIt3Wrapper_icon=Search_duplicates.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseAnsi=y
#AutoIt3Wrapper_Res_Comment=-
#AutoIt3Wrapper_Res_Description=Search_duplicates.exe
#AutoIt3Wrapper_Res_Fileversion=0.1.0.0
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=n
#AutoIt3Wrapper_Res_LegalCopyright=AZJIO
#AutoIt3Wrapper_Res_Language=1049
#AutoIt3Wrapper_Run_AU3Check=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Crypt.au3>
#include <File.au3>
#include <Array.au3>
#include <GUIConstantsEx.au3>
;#include <GuiListView.au3>
Global $Debug_LV = False
#include <ListViewConstants.au3>
#NoTrayIcon
Global $Stack[50], $Stack1[50]
Global $aArr, $a, $MD5Path, $Dubl
HotKeySet('{ESC}', "_Quit") ; выход по ESC
;создание оболочки
$Gui = GUICreate("Поиск дубликатов файлов", 500, 444, -1, -1, 0x00040000, 0x00000010) ; размер окна
$CatchDrop = GUICtrlCreateInput("", 0, 0, 500, 440)
GUICtrlSetState(-1, 136)
GUICtrlSetResizing(-1, 1)
$StatusBar = GUICtrlCreateLabel(@CRLF&'Строка состояния', 5, 380, 480, 30)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 2)
$restart = GUICtrlCreateButton("R", 480, 2, 18, 20)
GUICtrlSetTip(-1, "Перезапуск утилиты")
GUICtrlSetResizing(-1, 512 + 256 + 32 + 4)
$About = GUICtrlCreateButton("?", 460, 2, 18, 20)
GUICtrlSetTip(-1, "О программе")
GUICtrlSetResizing(-1, 512 + 256 + 32 + 4)
GUICtrlCreateLabel("используйте drag-and-drop", 170, 5, 160, 18)
GUICtrlSetResizing(-1, 32 + 256 + 512)
GUICtrlCreateLabel("Папки", 15, 10, 60, 17)
GUICtrlSetResizing(-1, 3 + 32 + 256 + 512)
$folder = GUICtrlCreateList("", 10, 25, 480, 100)
GUICtrlSetResizing(-1, 7 + 32 + 512)
GUICtrlCreateLabel("Дубликаты", 15, 132, 60, 18)
GUICtrlSetResizing(-1, 3 + 32 + 256 + 512)
_Dubl()
$context = GUICtrlCreateContextMenu($Dubl)
$contextOpen = GUICtrlCreateMenuitem ("Открыть",$context)
; $Select = GUICtrlCreateButton("Выбор", 180, 355, 70, 25)
; GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$Clear = GUICtrlCreateButton("Очистить", 260, 355, 70, 25)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$Search = GUICtrlCreateButton("Поиск", 340, 355, 70, 25)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$Delete = GUICtrlCreateButton("Удалить", 420, 355, 70, 25)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$aSizePath=''
$folderList = ''
$aArrOut=''
GUISetState()
_Crypt_Startup()
While 1
$msg = GUIGetMsg()
Select
; drag-and-drop - принятие каталогов
Case $msg = -13
$triger = 0
If @GUI_DropId = $CatchDrop Then
$aFolder = StringSplit(GUICtrlRead($CatchDrop), '|')
$GuiPos = WinGetPos($Gui)
GUICtrlSetPos($CatchDrop, $GuiPos[2], 0)
GUICtrlSetData($CatchDrop, '')
GUICtrlSetPos($CatchDrop, 0, 0)
For $i = 1 To $aFolder[0]
If StringInStr(FileGetAttrib($aFolder[$i]), "D") = 0 Then
$triger = 1
Else
GUICtrlSetData($folder, StringRegExpReplace($aFolder[$i], '(?:.*)\\(.*)$', '\1'))
$folderList &= '|' & $aFolder[$i]
EndIf
Next
EndIf
If $triger = 1 Then
$triger = 0
MsgBox(0, "Мелкая ошибка", 'Перетаскивайте каталоги, а не файлы.')
EndIf
Case $msg = $About
_About()
; Очистка (обнуляем все весомые переменные)
Case $msg = $Clear
GUICtrlDelete ($Dubl)
_Dubl()
$folderList = ''
GUICtrlSetData($folder, '')
$aSizePath = ''
$aArr = ''
$aArrT = ''
$TempMD5 = ''
$aArrOut = ''
$aArrMD5 = ''
GUICtrlSetData($StatusBar,@CRLF&'Строка состояния')
; Открыть
Case $msg = $contextOpen or $msg = $Dubl
ShellExecute(StringTrimRight(GUICtrlRead(GUICtrlRead ($Dubl)),1))
; Удаление
Case $msg = $Delete
If $folderList='' or $aArrOut='' Then ContinueLoop
GUICtrlSetData($StatusBar, 'Удаление выполняется...')
For $i = 1 to $aArrOut[0][0]
If GUICtrlRead($aArrOut[$i][0],1)=1 And FileExists($aArrOut[$i][1]) Then
FileDelete($aArrOut[$i][1])
GUICtrlDelete($aArrOut[$i][0])
$aArrOut[$i][0]=''
$aArrOut[$i][1]=''
EndIf
Next
_GUICtrlListView_SetColumnWidth($Dubl, 0, $LVSCW_AUTOSIZE)
If _GUICtrlListView_GetColumnWidth($Dubl, 0)<480 Then _GUICtrlListView_SetColumnWidth($Dubl, 0, 480)
GUICtrlSetData($StatusBar, 'Удаление завершено!')
; Поиск
Case $msg = $Search
If $folderList='' Then ContinueLoop
If $aSizePath<>'' Then ; перед повторным поиском делаем очистку
GUICtrlDelete ($Dubl)
_Dubl()
Sleep(50)
$aSizePath = ''
$aArr = ''
$aArrT = ''
$TempMD5 = ''
$aArrOut = ''
$aArrMD5 = ''
EndIf
GUICtrlSetData($StatusBar, 'Создание списка файлов...')
$aSizePath = ''
$timer = TimerInit()
If StringLeft($folderList, 1)='|' Then $folderList = StringTrimLeft($folderList, 1)
$aFolderList = StringSplit($folderList, '|')
For $i = 1 To $aFolderList[0] ; выполняем поиск в цикле для каждого добавленного пути
If FileExists($aFolderList[$i]) Then
FileFindNextFirst($aFolderList[$i])
While 1
$tempname = FileFindNext()
If $tempname = "" Then ExitLoop
$aSizePath &= '|' & FileGetSize($tempname) & '|' & $tempname
WEnd
EndIf
Next
$aArrT = StringSplit(StringTrimLeft($aSizePath, 1), "|") ;создаём одномерный массив, имитацию двумерного массива.
$aSizePath='1' ;очистка и индикатор выполненого поиска
;_ArrayDisplay($aArrT, "$aArrT") ; одномерный массив всех файлов (размер | путь)
;_ArrayDisplay($aArrT,"$aArrT",-1,-1,-1,-1, 'размер|путь') ; одномерный массив всех файлов (размер | путь)
Dim $aArr[$aArrT[0] / 2 + 1][2]
$aArr[0][0] = $aArrT[0] / 2
For $i = 1 To $aArrT[0]
If Mod($i, 2) = 0 Then
$aArr[$i / 2][0] = Int($aArrT[$i - 1])
$aArr[$i / 2][1] = $aArrT[$i]
EndIf
Next
; (массив | сортировка по возврастанию | начальный индекс сортировки | конечный | колонка сортировки)
_ArraySort($aArr, 0, 1, $aArr[0][0], 0)
;_ArrayDisplay($aArr, "$aArr") ; сортированный двумерный массив всех файлов (размер | путь)
$aArrOut = ''
Dim $aArrOut[1][2]
$a = 0
$0b = 0
$gp=0
$kol=0
$triger = 0
$triger2 = 0
$TempSize = ''
For $i = 1 To $aArr[0][0] ; формирование временного массива файлов c совпадающими размерами, но вместа размера указан MD5
$kol+=1
If $aArr[$i][0] = $TempSize Then
If $triger = 0 Then
$MD5Path = ''
$MD5Path &= '|' & _Crypt_HashFile($aArr[$i - 1][1], 0x00008003) & '|' & $aArr[$i - 1][1]
EndIf
$triger = 1
$MD5Path &= '|' & _Crypt_HashFile($aArr[$i][1], 0x00008003) & '|' & $aArr[$i][1]
Else
$triger = 0
EndIf
; переключение тригера для срабатывания обработки MD5 если совпадение существвали на последних элементах, чтоб правильно завершить цикл
If $aArr[0][0]=2 and $triger = 1 Then $triger2 = 1 ; исключение для всего двух одинаковых файлов
If $i = $aArr[0][0] Then $triger = 0
If $triger = 0 And $triger2 = 1 Then ; обработка временного массива с совпавшими размерами файлов ======================================
$aMD5PathT = StringSplit(StringTrimLeft($MD5Path, 1), "|") ;создаём одномерный массив, имитацию двумерного массива.
;_ArrayDisplay($aMD5PathT, "$aMD5PathT") ; сортированный массив всех файлов (размер | путь)
; конвертируем одномерный массив в двумерный.
Dim $aArrMD5[$aMD5PathT[0] / 2 + 1][2]
$aArrMD5[0][0] = $aMD5PathT[0] / 2
For $o = 1 To $aMD5PathT[0]
If Mod($o, 2) = 0 Then
$aArrMD5[$o / 2][0] = $aMD5PathT[$o - 1]
$aArrMD5[$o / 2][1] = $aMD5PathT[$o]
EndIf
Next
;_ArrayDisplay($aArrMD5, "$aArrMD5- до сортировки") ; временный сортированный массив совпавших по размеру файлов, но с разными MD5 (MD5 | путь)
_ArraySort($aArrMD5, 0, 1, $aArrMD5[0][0], 0)
;_ArrayDisplay($aArrMD5, "$aArrMD5- после сортировки") ; временный сортированный массив совпавших по размеру файлов, но с разными MD5 (MD5 | путь)
;===================================================================
; вложенная, подобная копия основного алгоритма, с разницей MD5 вместо размера
; формирование временного массива совпадающих файлов $aArrOut по MD5
$0triger = 0
$0triger2 = 0
$TempMD5 = ''
For $0i = 1 To $aArrMD5[0][0]
If $a-$0b < 3 Then
$a+=100
ReDim $aArrOut[$a][2]
EndIf
If $aArrMD5[$0i][0] = $TempMD5 Then
If $0triger = 0 Then
$0b += 1
$gp+=1
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&', текущий: '&$kol &', группа: '&$gp &', добавлено: '&$0b &', время: '& Ceiling(TimerDiff($timer)/1000)&' сек, размер: '& Ceiling($aArr[$i][0]/1000)& 'кб' &@CRLF& $aArrMD5[$0i - 1][1])
GUICtrlCreateListViewItem( '---'&$gp&'---',$Dubl)
GUICtrlSetColor(-1,0x777777)
GUICtrlSetBkColor ( -1, 0xffffff )
$aArrOut[$0b][0] = GUICtrlCreateListViewItem($aArrMD5[$0i - 1][1],$Dubl)
GUICtrlSetColor(-1,0xaa0000)
$aArrOut[$0b][1] = $aArrMD5[$0i - 1][1]
EndIf
$0triger = 1
$0b += 1
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&', текущий: '&$kol &', группа: '&$gp &', добавлено: '&$0b &', время: '& Ceiling(TimerDiff($timer)/1000) &' сек, размер: '& Ceiling($aArr[$i][0]/1000)& 'кб' &@CRLF& $aArrMD5[$0i][1])
$aArrOut[$0b][0] = GUICtrlCreateListViewItem($aArrMD5[$0i][1],$Dubl)
GUICtrlSetState(-1,1)
$aArrOut[$0b][1] = $aArrMD5[$0i][1]
Else
$0triger = 0
EndIf
$TempMD5 = $aArrMD5[$0i][0]
;_GUICtrlListView_SetColumn($Dubl, 0, ' ', 480)
Next
EndIf ;==================================================================================================================
If $triger = 1 Then
$triger2 = 1
Else
$triger2 = 0
EndIf
$TempSize = $aArr[$i][0]
_GUICtrlListView_SetColumnWidth($Dubl, 0, $LVSCW_AUTOSIZE)
Next
If _GUICtrlListView_GetColumnWidth($Dubl, 0)<480 Then _GUICtrlListView_SetColumnWidth($Dubl, 0, 480)
ReDim $aArrOut[$0b+1][2]
$aArrOut[0][0]=$0b
If $0b = 0 Then
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&' файлов, дубликатов не найдено!')
Else
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&', групп: '&$gp &', добавлено: '&$0b&', отмечено: '&$0b-$gp &', время: '& Ceiling(TimerDiff($timer)/1000)&' сек' &@CRLF& 'Готово!')
EndIf
;_ArrayDisplay($aArrOut, "$aArrOut")
; Перезапуск
Case $msg = $restart
_restart()
Case $msg = -3
_Crypt_Shutdown()
Exit
EndSelect
WEnd
; добавлено из ListViewConstants.au3, для экономии размера скрипта
Func _GUICtrlListView_SetColumnWidth($hWnd, $iCol, $iWidth)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If IsHWnd($hWnd) Then
Return _SendMessage($hWnd, $LVM_SETCOLUMNWIDTH, $iCol, $iWidth)
Else
Return GUICtrlSendMsg($hWnd, $LVM_SETCOLUMNWIDTH, $iCol, $iWidth)
EndIf
EndFunc
Func _GUICtrlListView_GetColumnWidth($hWnd, $iCol)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If IsHWnd($hWnd) Then
Return _SendMessage($hWnd, $LVM_GETCOLUMNWIDTH, $iCol)
Else
Return GUICtrlSendMsg($hWnd, $LVM_GETCOLUMNWIDTH, $iCol, 0)
EndIf
EndFunc
Func _Dubl()
$GuiPos = WinGetPos($Gui)
$Dubl = GUICtrlCreateListView(' ', 10, 150, $GuiPos[2]-26, $GuiPos[3]-251, $LVS_NOCOLUMNHEADER +$LVS_SHOWSELALWAYS, $LVS_EX_CHECKBOXES + $LVS_OWNERDRAWFIXED)
GUICtrlSendMsg($Dubl, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlSendMsg($Dubl, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_TRACKSELECT, $LVS_EX_TRACKSELECT)
GUICtrlSetBkColor(-1, 0xf0f0f0) ; 0xE0DFE3 - цвет стандартный серый
GUICtrlSetResizing(-1, 7 + 32 + 64)
EndFunc
;========================================
; функция поиска всех файлов в каталоге (NIKZZZZ)
Func FileFindNextFirst($FindCat)
$Stack[0] = 1
$Stack1[1] = $FindCat
$Stack[$Stack[0]] = FileFindFirstFile($Stack1[$Stack[0]] & "\*.*")
Return $Stack[$Stack[0]]
EndFunc ;==>FileFindNextFirst
Func FileFindNext()
While 1
$file = FileFindNextFile($Stack[$Stack[0]])
If @error Then
FileClose($Stack[$Stack[0]])
If $Stack[0] = 1 Then
Return ""
Else
$Stack[0] -= 1
ContinueLoop
EndIf
Else
If StringInStr(FileGetAttrib($Stack1[$Stack[0]] & "\" & $file), "D") > 0 Then
$Stack[0] += 1
$Stack1[$Stack[0]] = $Stack1[$Stack[0] - 1] & "\" & $file
$Stack[$Stack[0]] = FileFindFirstFile($Stack1[$Stack[0]] & "\*.*")
ContinueLoop
Else
Return $Stack1[$Stack[0]] & "\" & $file
EndIf
EndIf
WEnd
EndFunc ;==>FileFindNext
Func _restart()
Local $sAutoIt_File = @TempDir & "\~Au3_ScriptRestart_TempFile.au3"
Local $sRunLine, $sScript_Content, $hFile
$sRunLine = @ScriptFullPath
If Not @Compiled Then $sRunLine = @AutoItExe & ' /AutoIt3ExecuteScript ""' & $sRunLine & '""'
If $CmdLine[0] > 0 Then $sRunLine &= ' ' & $CmdLineRaw
$sScript_Content &= '#NoTrayIcon' & @CRLF & _
'While ProcessExists(' & @AutoItPID & ')' & @CRLF & _
' Sleep(10)' & @CRLF & _
'WEnd' & @CRLF & _
'Run("' & $sRunLine & '")' & @CRLF & _
'FileDelete(@ScriptFullPath)' & @CRLF
$hFile = FileOpen($sAutoIt_File, 2)
FileWrite($hFile, $sScript_Content)
FileClose($hFile)
Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sAutoIt_File & '"', @ScriptDir, @SW_HIDE)
Sleep(1000)
Exit
EndFunc ;==>_restart
Func _Quit()
Exit
EndFunc ;==>_Quit
Func _About()
GUISetState(@SW_HIDE, $Gui)
$font="Arial"
$Gui1 = GUICreate("О программе", 270, 180, -1, -1, -1, 0x00000080)
GUISetBkColor (0xf8c848)
GUICtrlCreateLabel('Search duplicates', 0, 20, 270, 23, 0x01)
GUICtrlSetFont (-1,15, 600, -1, $font)
GUICtrlSetColor(-1,0xa21a10)
GUICtrlCreateLabel('поиск дубликатов файлов', 0, 49, 270, 46, 0x01)
GUICtrlSetFont (-1,13, 600, -1, $font)
GUISetFont (9, 600, -1, $font)
GUICtrlSetColor(-1,0xa21a10)
GUICtrlCreateLabel('Версия 0.1 от 9.07.2010', 55, 100, 210, 17)
GUICtrlCreateLabel('Сайт:', 55, 115, 40, 17)
$url=GUICtrlCreateLabel('http://azjio.ucoz.ru', 92, 115, 170, 17)
GUICtrlSetCursor(-1, 0)
GUICtrlSetColor(-1, 0x0000ff)
GUICtrlCreateLabel('WebMoney: R939163939152', 55, 130, 210, 17)
GUICtrlCreateLabel('Copyright AZJIO © 2010', 55, 145, 210, 17)
GUISetState(@SW_SHOW, $Gui1)
$msg = $Gui1
While 1
$msg = GUIGetMsg()
Select
Case $msg = $url
ShellExecute ('http://azjio.ucoz.ru')
Case $msg = -3
$msg = $Gui
GUIDelete($Gui1)
GUISetState(@SW_SHOW, $Gui)
ExitLoop
EndSelect
WEnd
EndFunc