Что нового

[Файловая система] Копирование файлов, отображение прогресса копирования в GUI

Mancoffee

Свет проталкивает тьму ...
Сообщения
86
Репутация
1
joiner
Ага :whistle:

Я правильно понимаю, что к примеру у меня есть кнопка "$BtExit", я её переименовал в "$ButtonStop" (во втором скрипте, последняя функция). Она то и должна отвечать за остановку. Правильно?
Если да, то она этого не делает, то есть в процессе копирования если нажать, то ничего не происходит.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
нет не правильно
Код:
_CopyDirCopyFile($FileSourch, $FileDest, $ProgressBar = '', $FolderCopy = 1, $FileCopy = 1, $ButtonFuncStop = '')

читай внимательно описание функции на предыдущей странице и сам пример - сообщение 13
в твоем скрипте свои идентификаторы кнопок ( то есть переменные), соответственно в твоем случае будет выглядеть так
Код:
_CopyDirCopyFile("исходный путь", "путь назначения", $Progress, 1, 1, $BtExit)



Добавлено:
Сообщение автоматически объединено:

в самой функции ничего менять не надо


Добавлено:
Сообщение автоматически объединено:

Mancoffee, вот тебе на затравку третий вариант (расширенный) функции с возможность паузы копирования :smile:
пауза это опционально . необязательно.
вот пример

Код:
#include <FileOperations.au3>
#include <File.au3>

$Form1 = GUICreate("Form1", 491, 128, 360, 419)
$Progress1 = GUICtrlCreateProgress(24, 32, 422, 17)
$Button1 = GUICtrlCreateButton("Start", 50, 72, 75, 25)
$Button2 = GUICtrlCreateButton('Stop', 150, 72, 75, 25)
$Button3 = GUICtrlCreateButton('Pause', 250, 72, 75, 25)
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case -3
			Exit
		Case $Button1
			;$sourch = FileSelectFolder('', '', 1 + 2 + 4, '', $Form1); 3-4
			$sourch = FileOpenDialog('', '', '(*.*)', 1 + 4, '', $Form1) ; 3-4
			$dest = FileSelectFolder('', '', 1 + 2 + 4, '', $Form1);
			;$dest = FileSaveDialog('', '', '(*.*)', 16, '', $Form1);
			$ret = _CopyDirCopyFile($sourch, $dest, $Progress1, 1, 1, $Button2, $Button3)
			ConsoleWrite($ret & @CRLF)
	EndSwitch
WEnd

Func _CopyDirCopyFile($FileSourch, $FileDest, $ProgressBar = '', $FolderCopy = 1, $FileCopy = 1, $ButtonFuncStop = '', $ButtonPauseFunc = '')
    If Not $FileSourch Then Return 1
    If Not $FileDest Then Return 2
    Global $ButtonStop = $ButtonFuncStop, $ButtonPause = $ButtonPauseFunc,$ExitFunc = 0,$Pause = 0
    Local $s = 4096, $a = 1, $b = 1, $size_all = 0, $flag = 0, $DataButtonPause = GUICtrlRead($ButtonPauseFunc)
    Dim $szDrive, $szDir, $szFName, $szExt, $Drive, $Dir, $FName, $Ext
    $pathcheck = _PathSplit($FileDest, $Drive, $Dir, $FName, $Ext)
    If $pathcheck[1] = '' Then Return 4
    $var_string = StringReplace($FileSourch, "|", '\', 1)
    $path = _PathSplit($var_string, $szDrive, $szDir, $szFName, $szExt)
    $attrib_fd = FileGetAttrib($FileSourch)
    $fd_s = StringInStr($attrib_fd, 'D')
    If Not $fd_s = 0 Then
        $flag = 1
        $dir_name = StringRegExpReplace($FileSourch, '.*\\', '')
        Select
            Case $FolderCopy = 0
                If FileExists($FileDest & '\' & $dir_name) Then
                    $dirname = $FileDest & '\' & $dir_name & '_' & @SEC & @MSEC
                    $result = _FO_FileSearch($FileSourch, '*', True, 125)
                    If @error Then
                        $dircopy = DirCopy($FileSourch, $dirname)
                        If $dircopy = 0 Then
                            Return 3
                        Else
                            GUICtrlSetData($ProgressBar, 100)
                            Sleep(1000)
                            GUICtrlSetData($ProgressBar, '')
                            Return 0
                        EndIf
                    EndIf
                Else
                    $dirname = $FileDest & '\' & $dir_name
                    $result = _FO_FileSearch($FileSourch, '*', True, 125)
                    If @error Then
                        $dircopy = DirCopy($FileSourch, $dirname)
                        If $dircopy = 0 Then
                            Return 3
                        Else
                            GUICtrlSetData($ProgressBar, 100)
                            Sleep(1000)
                            GUICtrlSetData($ProgressBar, '')
                            Return 0
                        EndIf
                    EndIf
                EndIf
            Case $FolderCopy = 1
                $dirname = $FileDest & '\' & $dir_name
                $result = _FO_FileSearch($FileSourch, '*', True, 125)
                If @error Then
                    $replacepath = StringReplace($path[1] & $path[2], '\', '', -1)
                    $compare = StringCompare($FileDest, $replacepath)
                    If $compare = 0 Then
                        Return 3
                    Else
                        $dircopy = DirCopy($FileSourch, $dirname, 1)
                        If $dircopy = 0 Then
                            Return 3
                        Else
                            GUICtrlSetData($ProgressBar, 100)
                            Sleep(1000)
                            GUICtrlSetData($ProgressBar, '')
                            Return 0
                        EndIf
                    EndIf
                Else
                    $replacepath = StringReplace($path[1] & $path[2], '\', '', -1)
                    $compare = StringCompare($FileDest, $replacepath)
                    If $compare = 0 Then
                        Return 3
                    EndIf
                EndIf
        EndSelect
    Else
        $flag = 2
        $replace = StringReplace($var_string, '|', '*' & $path[1] & $path[2])
        $result = StringSplit($replace, '*')
        If $result[0] = 1 Then
            If FileExists($result[1]) = 0 Then
                Return 1
            EndIf
        EndIf
        $attrib_f = FileGetAttrib($FileDest)
        $f_s = StringInStr($attrib_f, 'D')
    EndIf
    For $i = 1 To $result[0]
        $size = FileGetSize($result[$i])
        $size_all += $size
    Next
    $round = Ceiling($size_all / $s)
    $step = Ceiling($round / 100)
    $z = 0
    $x = 0
    GUIRegisterMsg(0x0111, 'WM_COMMAND')
    For $r = 1 To $result[0]
        If $Pause = 1 Then
            GUICtrlSetData($ButtonPause, 'Proceed')
            While 1
                If $Pause = 0 Then
                    GUICtrlSetData($ButtonPause, $DataButtonPause)
                    ExitLoop
                EndIf
                If $ExitFunc = 1 Then
                    GUICtrlSetData($ButtonPause, $DataButtonPause)
                    ExitLoop
                EndIf
                Sleep(100)
            WEnd
        EndIf
        If $ExitFunc = 1 Then
            GUICtrlSetData($ProgressBar, '')
            Return 6
        EndIf
        Select
            Case $flag = 1
                Select
                    Case $FileCopy = 0
                        If FileExists($dirname & StringReplace($result[$r], $FileSourch, '', 1)) Then
                            $filenamestring = StringRegExpReplace($dirname & StringReplace($result[$r], $FileSourch, '', 1), '.*\\', '')
                            $pathreplace = StringReplace($dirname & StringReplace($result[$r], $FileSourch, '', 1), $filenamestring, '', -1)
                            $filedestname = $pathreplace & @SEC & @MSEC & '_' & $filenamestring
                        Else
                            $filedestname = $dirname & StringReplace($result[$r], $FileSourch, '', 1)
                            If FileExists($filedestname) Then FileSetAttrib($filedestname,'-R')
                        EndIf
                    Case $FileCopy = 1
                        $filedestname = $dirname & StringReplace($result[$r], $FileSourch, '', 1)
                        If FileExists($filedestname) Then FileSetAttrib($filedestname,'-R')
                EndSelect
            Case $flag = 2
                If Not $f_s = 0 Then
                    Select
                        Case $FileCopy = 0
                            If FileExists($FileDest & '\' & StringRegExpReplace($result[$r], '.*\\', '')) Then
                                $filenamestring = StringRegExpReplace($result[$r], '.*\\', '')
                                $pathreplace = StringReplace($FileDest, $filenamestring, '', -1)
                                $filedestname = $pathreplace & '\' & @SEC & @MSEC & '_' & $filenamestring
                            Else
                                $filedestname = $FileDest & '\' & StringRegExpReplace($result[$r], '.*\\', '')
                                If FileExists($filedestname) Then FileSetAttrib($filedestname,'-R')
                            EndIf
                        Case $FileCopy = 1
                            $filedestname = $FileDest & '\' & StringRegExpReplace($result[$r], '.*\\', '')
                            If FileExists($filedestname) Then FileSetAttrib($filedestname,'-R')
                    EndSelect
                Else
                    $filedestname = $FileDest
                EndIf
        EndSelect
        $hFile = FileOpen($result[$r], 16)
        If $hFile = -1 Then
            $z = $z + 1
            ContinueLoop
        EndIf
        $folderdestname = FileOpen($filedestname, 2 + 8 + 16)
        If $folderdestname = -1 Then
            FileClose($hFile)
            $x = $x + 1
            ContinueLoop
        EndIf
        While 1
            If $Pause = 1 Then
                GUICtrlSetData($ButtonPause, 'Proceed')
                While 1
                    If $Pause = 0 Then
                        GUICtrlSetData($ButtonPause, $DataButtonPause)
                        ExitLoop
                    EndIf
                    If $ExitFunc = 1 Then
                        GUICtrlSetData($ButtonPause, $DataButtonPause)
                        ExitLoop
                    EndIf
                    Sleep(100)
                WEnd
            EndIf
            If $ExitFunc = 1 Then
                GUICtrlSetData($ProgressBar, '')
                FileClose($hFile)
                FileClose($folderdestname)
                FileDelete($filedestname)
                Return 6
            EndIf
            $sChars = FileRead($hFile, $s)
            If @error = -1 Then
                ExitLoop
            ElseIf @error = 1 Then
                ExitLoop
            EndIf
            $file_w = FileWrite($folderdestname, $sChars)
            If $file_w = 0 Then ExitLoop
            If $b = $step * $a Then
                GUICtrlSetData($ProgressBar, $a)
                $a = $a + 1
            EndIf
            $b = $b + 1
            If $b = $round Then
                GUICtrlSetData($ProgressBar, 100)
            EndIf
        WEnd
        FileClose($hFile)
        FileClose($folderdestname)
        $attrib = FileGetAttrib($result[$r])
        FileSetAttrib($filedestname, $attrib)
    Next
    $emptyfolder = _FO_SearchEmptyFolders($FileSourch, 1)
    If Not @error Then
        For $i = 1 To $emptyfolder[0]
            $pathdestreplace = StringReplace($emptyfolder[$i], '\', '', -1)
            $emptyfoldername = $dirname & StringReplace($pathdestreplace, $FileSourch, '', 1)
            DirCreate($emptyfoldername)
        Next
    EndIf
  GUIRegisterMsg(0x0111, '')
    If $z = 0 And $x = 0 Then
        GUICtrlSetData($ProgressBar, 100)
        Sleep(1000)
        GUICtrlSetData($ProgressBar, '')
        Return 0
    ElseIf $z = UBound($result) - 1 Or $x = UBound($result) - 1 Then
        Return 4
    Else
        GUICtrlSetData($ProgressBar, 100)
        Sleep(1000)
        GUICtrlSetData($ProgressBar, '')
        Return 5
    EndIf
EndFunc   ;==>_CopyDirCopyFile

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $nID = BitAND($wParam, 0xFFFF)
    Switch $nNotifyCode
        Case 0
            Switch $nID
				Case $ButtonStop
                    $ExitFunc = 1
    GUIRegisterMsg(0x0111, '')
                Case $ButtonPause
                    If $Pause = 0 Then
                        $Pause = 1
                    Else
                        $Pause = 0
                    EndIf
            EndSwitch
    EndSwitch
    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_COMMAND
единственный момент это при нажатии кнопки паузы происходит смена надписи на кнопке. Появится надпись Proceed , то есть "продолжить". при повторном нажатии вернется старое название. это уже, конечно, вольности. но все же.
пробуй :smile:


Добавлено:
Сообщение автоматически объединено:

исправил ошибку невозможности перезаписи файлов из-за того, что файл имеет атрибут "Только чтение".
исправлено во всех трех примерах
 

Mancoffee

Свет проталкивает тьму ...
Сообщения
86
Репутация
1
joiner
Попробовал, только не пойму, как привязать скрипт с массивом к этому :stars:
Или он (скрипт с паузой) не работает, потому что я дал свои названия переменных?


Добавлено:
Сообщение автоматически объединено:

joiner [?]
Код:
_CopyDirCopyFile("исходный путь", "путь назначения", $Progress, 1, 1, $BtExit)
Это для каждой папки/файлов нужно прописывать?


Добавлено:
Сообщение автоматически объединено:

joiner [?]
вот тебе на затравку
Действительно уж ... :smile:
Запутался я уже

Правильно я думаю, что функцию скрипт (последний) мне нужно поместить в это место (то есть в цикл)
Код:
#NoTrayIcon
;#include <MyFile.au3>
#include <Array.au3>
#include <WindowsConstants.au3>

$MainWin= GUICreate('Сохранение настроек', 350, 128, -1, 568)
$Progress = GUICtrlCreateProgress(24, 32, 300, 17)
$BtStart = GUICtrlCreateButton("Старт", 40, 60, 75, 25)
$BtPause = GUICtrlCreateButton("Пауза", 136, 60, 75, 25)
$BtReg = GUICtrlCreateButton("RegOut", 136, 97, 75, 25)
$BtExit = GUICtrlCreateButton('Выйти', 230, 60, 75, 25)
$NameCopy = GUICtrlCreateLabel('', 24, 15, 300, 17)
$Count = GUICtrlCreateLabel('', 325, 15, 300, 25)
GUISetState(@SW_SHOW)
WinSetOnTop('Сохранение настроек', '', 1)

$AppDataLocalDir = 'c:\Users\Стрэк\AppData\Local'
$AppDataLocalDirHome = 'd:\Saves\Programs\Users\Strek\AppData\Local'
$AppDataDirHome = 'd:\Saves\Programs\Users\Strek\AppData\Roaming'
$ProgramDataDir = 'C:\ProgramData'
$ProgramDataDirHome = 'd:\Saves\Programs\Users\Strek\ProgramData'

Dim $array[22][2]
$array[1][0] = @AppDataDir & "\Adobe\Adobe Photoshop CS6\Adobe Photoshop CS6 Settings"
$array[2][0] = @AppDataDir & '\Adobe\Adobe Illustrator CS6 Settings'
$array[3][0] = @AppDataDir & '\Adobe\Dreamweaver CS6\Configuration'
$array[4][0] = $AppDataLocalDir & '\Adobe\Flash CS6'
$array[5][0] = @AppDataDir & "\Console"
$array[6][0] = @AppDataDir & '\IndigoRose'
$array[7][0] = @AppDataDir & '\Corel\CorelDRAW Graphics Suite X6'
$array[8][0] = @AppDataDir & '\FileZilla'
$array[9][0] = @AppDataDir & '\NetBeans'
$array[10][0] = @AppDataDir & '\Htpasswd Generator'
$array[11][0] = @AppDataDir & '\SkyMonk'
$array[12][0] = $AppDataLocalDir & '\StarDock\ObjectDockPlus'
$array[13][0] = $AppDataLocalDir & '\Yandex\Praetorian\'
$array[14][0] = @AppDataDir & '\WinRAR\Themes'
$array[15][0] = @AppDataDir & '\Hulubulu\HotKeyMan\Data'
$array[16][0] = @AppDataDir & '\Synaptics\Profiles'
$array[17][0] = $ProgramDataDir & '\Solo9'
$array[18][0] = @AppDataDir & '\Mozilla\Firefox\profiles.ini'
$array[19][0] = @AppDataDir & '\DAEMON Tools Pro\ImageCatalog.xml'
$array[20][0] =@AppDataDir & '\DVDVideoSoft\FreeAudioConverter\FreeAudioConverterProfile.xml'
$array[21][0] = @AppDataDir & '\Microsoft\Windows\Start Menu\Programs\My Apps'
;$array[20][0] =

$array[1][1] = $AppDataDirHome & '\Adobe\Adobe Photoshop CS6\'
$array[2][1] = $AppDataDirHome & '\Adobe\'
$array[3][1] = $AppDataDirHome & '\Adobe\Dreamweaver CS6'
$array[4][1] = $AppDataLocalDirHome & '\Adobe\'
$array[5][1] = $AppDataDirHome
$array[6][1] = $AppDataLocalDirHome
$array[7][1] = $AppDataDirHome & '\Corel\'
$array[8][1] = $AppDataDirHome
$array[9][1] = $AppDataDirHome
$array[10][1] = $AppDataDirHome
$array[11][1] = $AppDataDirHome
$array[12][1] = $AppDataLocalDirHome & '\StarDock\'
$array[13][1] = $AppDataLocalDir & '\Yandex\'
$array[14][1] =  $AppDataDirHome & '\WinRAR\'
$array[15][1] = $AppDataDirHome & '\Hulubulu\HotKeyMan\'
$array[16][1] = $AppDataDirHome & '\Synaptics\'
$array[17][1] = $ProgramDataDirHome & '\Solo9\'
$array[18][1] = 'd:\Programs\TotalCommander\Launching\Soft\Internet\Firefox\Data\'
$array[19][1] = $AppDataDirHome & '\DAEMON Tools Pro\ImageCatalog.xml'
$array[20][1] = $AppDataDirHome & '\DVDVideoSoft\FreeAudioConverter\FreeAudioConverterProfile.xml'
$array[21][1] = $AppDataDirHome & '\Microsoft\Windows\Start Menu\Programs\'
;$array[22][1] =

;_ArrayDisplay($array)

While 1
СЮДА?
WEnd
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Mancoffee [?]
Это для каждой папки/файлов нужно прописывать?
да, но мы же уже обсуждали пример с использованием массива. http://autoit-script.ru/index.php/topic,13191.msg84918.html#msg84918
Действительно уж
все так же как и с другими функциями. менять ничего не надо. просто вписываешь правильные параметры и все.


Добавлено:
Сообщение автоматически объединено:

Код:
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            Exit
        Case $BtStart
            For $i = 1 To UBound($array) - 1
				GUICtrlSetData($Count, $i)
                GUICtrlSetData($NameCopy, StringRegExpReplace($array[$i][0],'.*\\', ''))
                $ret = _CopyDirCopyFile($array[$i][0], $array[$i][1], $Progress,1,1,$BtExit,$BtPause)
				ConsoleWrite($ret&@CRLF)
            Next
            GUICtrlSetData($NameCopy, '')
            GUICtrlSetData($Count, '')
    EndSwitch
WEnd



Добавлено:
Сообщение автоматически объединено:

Mancoffee
только нужно учесть момент, что при копировании небольших файлов навряд ли получится остановить или поставить на паузу.
руководить процессом успешно можно будет при копировании достаточно больших файлов или папок ( в массиве вместо пути к файлам можно использовать путь к папкам)
есть задумка переработать функцию, чтобы она могла работать с путями, которые поступают в виде массива. но пока это задумка.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
сделал изменения в функции. теперь в качестве входящих данных можно использовать массив путей или получать пути функциями открытия или выбора файлов и папок.
функция работает только с двумерным массивом.
также есть привязка кнопкам окна для того, чтобы можно было остановить процесс, продолжить или выгрузить функцию
смотри пример
Код:
#include <FileOperations.au3>
#include <File.au3>
#include <array.au3>

Dim $array[1][2]
$array[0][0] = 'Путь к папке или файлу'
$array[0][1] = 'Папка назначения'
;массив должен быть только двумерным. с любым количеством строк - $array[$n][2]


$MainWin = GUICreate('_CopyDirCopyFile', 500, 128, -1, -1)
$Progress = GUICtrlCreateProgress(24, 32, 450, 17)
$BtStart = GUICtrlCreateButton("Старт", 40, 60, 75, 25)
$BtPause = GUICtrlCreateButton("Пауза", 136, 60, 75, 25)
$BtExit = GUICtrlCreateButton('Стоп', 230, 60, 75, 25)
GUISetState(@SW_SHOW)


While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case -3
			Exit
		Case $BtStart
			;$Source = FileSelectFolder('', '', 1 + 2 + 4, '', $MainWin)
			;$Source = FileOpenDialog('', '', '(*.*)', 1 + 4, '', $MainWin)
			;$Dest = FileSelectFolder('', '', 1 + 2 + 4, '', $MainWin);
			;$Dest = FileSaveDialog('', '', '(*.*)', 16, '', $MainWin);
			$ret = _CopyDirCopyFile($array, '', 1, 1, 1, $Progress, $BtExit, $BtPause); данные для копирования берутся из массива
			;$ret = _CopyDirCopyFile($Source, $Dest, 0, 1, 1, $Progress, $BtExit, $BtPause); исходный путь и путь назначения получаются не из массива. функциями открытия файла или выбора папки.
			ConsoleWrite($ret & @CRLF)
	EndSwitch
WEnd

; Функция ====================================================================================================
; Имя.................:  _CopyDirCopyFile
; Синтаксис...........: _CopyDirCopyFile($FileSource, $FileDest, $CopyArray = 0, $FolderCopy = 1, $FileCopy = 1, $ProgressBar = '', $ButtonFuncStop = '', $ButtonPauseFunc = '')
; Назначение..........: Копирование файлов и папок, отображение процесса копирования в элементе, созданном функцией GUICtrlCreateProgress
; Параметры...........: $FileSource - Копируемые файлы или папки (возможен выбор нескольких файлов)
;                       $FileDest  - Путь копирования.При использовании массива оставить пустое значение  - ""
;                       |$CopyArray = 0 (по умолчанию) - исходный путь и путь назначения не массив
;                       |$CopyArray = 1  - исходный путь и путь назначения массив
;                       |$FolderCopy = 1 (по умолчанию)  - Если в месте назначения есть папка с таким же именем, то она будет перезаписана.
;                       |$FolderCopy = 0 - Если в месте назначения есть папка с таким же именем, то у копируемой папки будет изменено имя
;                       |$FileCopy = 1 (по умолчанию) - Файлы со сходными именами в месте назначения будут перезаписаны
;                       |$FileCopy = 0 - будут созданы копии файлов, имена которых совпадают
;                       |$ProgressBar  = '' (по умолчанию) - Переменная элемента, созданного функцией GUICtrlCreateProgress
;                       |$ButtonFuncStop = '' (по умолчанию) - Переменная элемента (кнопки) для остановки функции
;                       |$ButtonPauseFunc = '' (по умолчанию) - Переменная элемента (кнопки) для паузы функции
;Возвращаемые значения: 0 - успешное выполнение
;                       1 - исходный путь не существует
;                       2 - путь назначения не существует
;                       3 - $FileSource не является массивом или это не двумерный массив
;                       4 - файлы или папки не скопированы, неверен путь\не найдены файлы или нет прав на чтение\запись
;                       5 - некоторые файлы не скопированы
;                       6 - остановка функции пользователем
; =============================================================================================================
Func _CopyDirCopyFile($FileSource, $FileDest, $CopyArray = 0, $FolderCopy = 1, $FileCopy = 1, $ProgressBar = '', $ButtonFuncStop = '', $ButtonPauseFunc = '')

	Global $ButtonStop = $ButtonFuncStop, $ButtonPause = $ButtonPauseFunc, $ExitFunc = 0, $Pause = 0
	Local $s = 4096, $a = 1, $b = 1, $size_all = 0, $flag = 0, $guimsg = 0, $result
	Local $filesearchsizeall = 0, $filesize = 0, $filesize_all = 0, $z = 0, $x = 0, $y = 0, $p = 0, $null = 0

	If Not $ButtonFuncStop = '' And Not $ButtonPauseFunc = '' Then
		GUIRegisterMsg(0x0111, 'WM_COMMAND_Copy_Gui')
		Local $DataButtonPause = GUICtrlRead($ButtonPauseFunc)
		$guimsg = 1
	ElseIf Not $ButtonFuncStop = '' Then
		GUIRegisterMsg(0x0111, 'WM_COMMAND_Copy_Gui')
		$guimsg = 1
	ElseIf Not $ButtonPauseFunc = '' Then
		GUIRegisterMsg(0x0111, 'WM_COMMAND_Copy_Gui')
		Local $DataButtonPause = GUICtrlRead($ButtonPauseFunc)
		$guimsg = 1
	EndIf

	Select
		Case $CopyArray = 0
			Dim $ArrayFileCopy[1][2]
			$ArrayFileCopy[0][0] = $FileSource
			$ArrayFileCopy[0][1] = $FileDest
			If $ArrayFileCopy[0][0] = '' Then Return 1
			If $ArrayFileCopy[0][1] = '' Then Return 2
		Case $CopyArray = 1
			If UBound($FileSource, 0) = 2 Then
				Dim $ArrayFileCopy[UBound($FileSource)][2]
				For $i = 0 To UBound($FileSource) - 1
					$ArrayFileCopy[$i][0] = $FileSource[$i][0]
					$ArrayFileCopy[$i][1] = $FileSource[$i][1]
				Next
			Else
				Return 3
			EndIf
			For $i = 0 To UBound($ArrayFileCopy) - 1
				If $ArrayFileCopy[$i][0] = '' Or $ArrayFileCopy[$i][1] = '' Then ContinueLoop
				$filesearch = _FO_FileSearch($ArrayFileCopy[$i][0], '*', True, 125, 1, 2)
				If Not @error Then
					For $t = 0 To UBound($filesearch) - 1
						$filesearchsize = FileGetSize($filesearch[$t])
						$filesearchsizeall += $filesearchsize
					Next
				Else
					$filepathsize = FileGetSize($ArrayFileCopy[$i][0])
					$filesize += $filepathsize
				EndIf
			Next
			$filesize_all = $filesearchsizeall + $filesize
			$round = Ceiling($filesize_all / $s)
			$step = Ceiling($round / 100)
	EndSelect

	Dim $szDrive, $szDir, $szFName, $szExt, $Drive, $Dir, $FName, $Ext

	For $ar = 0 To UBound($ArrayFileCopy) - 1
		If $ArrayFileCopy[$ar][0] = '' Or $ArrayFileCopy[$ar][1] = '' Then
			$null += 1
			ContinueLoop
		EndIf
		If $Pause = 1 Then
			GUICtrlSetData($ButtonPause, 'Proceed')
			While 1
				If $Pause = 0 Then
					GUICtrlSetData($ButtonPause, $DataButtonPause)
					ExitLoop
				EndIf
				If $ExitFunc = 1 Then
					GUICtrlSetData($ButtonPause, $DataButtonPause)
					ExitLoop
				EndIf
				Sleep(100)
			WEnd
		EndIf
		If $ExitFunc = 1 Then
			GUICtrlSetData($ProgressBar, '')
			Return 6
		EndIf
		$pathcheck = _PathSplit($ArrayFileCopy[$ar][1], $Drive, $Dir, $FName, $Ext)
		If $pathcheck[1] = '' Or FileExists($pathcheck[1]) = 0 Then
			$y += 1
			ContinueLoop
		EndIf
		$var_string = StringReplace($ArrayFileCopy[$ar][0], "|", '\', 1)
		$path = _PathSplit($var_string, $szDrive, $szDir, $szFName, $szExt)
		$attrib_fd = FileGetAttrib($ArrayFileCopy[$ar][0])
		$fd_s = StringInStr($attrib_fd, 'D')
		If Not $fd_s = 0 Then
			$flag = 1
			$dir_name = StringRegExpReplace($ArrayFileCopy[$ar][0], '.*\\', '')
			Select
				Case $FolderCopy = 0
					If FileExists($ArrayFileCopy[$ar][1] & '\' & $dir_name) Then
						$dirname = $ArrayFileCopy[$ar][1] & '\' & $dir_name & '_' & @SEC & @MSEC
						$result = _FO_FileSearch($ArrayFileCopy[$ar][0], '*', True, 125, 1, 2)
						If @error Then
							$dircopy = DirCopy($ArrayFileCopy[$ar][0], $dirname)
							ContinueLoop
							If $dircopy = 0 Then
								$y += 1
								ContinueLoop
							EndIf
						EndIf
					Else
						$dirname = $ArrayFileCopy[$ar][1] & '\' & $dir_name
						$result = _FO_FileSearch($ArrayFileCopy[$ar][0], '*', True, 125, 1, 2)
						If @error Then
							$dircopy = DirCopy($ArrayFileCopy[$ar][0], $dirname)
							ContinueLoop
							If $dircopy = 0 Then
								$y += 1
								ContinueLoop
							EndIf
						EndIf
					EndIf
				Case $FolderCopy = 1
					$dirname = $ArrayFileCopy[$ar][1] & '\' & $dir_name
					$result = _FO_FileSearch($ArrayFileCopy[$ar][0], '*', True, 125, 1, 2)
					If @error Then
						$replacepath = StringReplace($path[1] & $path[2], '\', '', -1)
						$compare = StringCompare($ArrayFileCopy[$ar][1], $replacepath)
						If $compare = 0 Then
							$y += 1
							ContinueLoop
						Else
							$dircopy = DirCopy($ArrayFileCopy[$ar][0], $dirname, 1)
							ContinueLoop
							If $dircopy = 0 Then
								$y += 1
								ContinueLoop
							EndIf
						EndIf
					Else
						$replacepath = StringReplace($path[1] & $path[2], '\', '', -1)
						$compare = StringCompare($ArrayFileCopy[$ar][1], $replacepath)
						If $compare = 0 Then
							$y += 1
							ContinueLoop
						EndIf
					EndIf
			EndSelect
		Else
			$flag = 2
			Select
				Case $CopyArray = 0
					$replace = StringReplace($var_string, '|', '*' & $path[1] & $path[2])
					$result = StringSplit($replace, '*', 2)
					If UBound($result) = 1 Then
						If FileExists($result[0]) = 0 Then
							$y += 1
							ContinueLoop
						EndIf
					EndIf
					For $i = 0 To UBound($result) - 1
						$filesize = FileGetSize($result[$i])
						$filesize_all += $filesize
					Next
					$round = Ceiling($filesize_all / $s)
					$step = Ceiling($round / 100)
				Case $CopyArray = 1
					Dim $result[1]
					$result[0] = $ArrayFileCopy[$ar][0]
			EndSelect
			$attrib_f = FileGetAttrib($ArrayFileCopy[$ar][1])
			$f_s = StringInStr($attrib_f, 'D')
		EndIf

		For $r = 0 To UBound($result) - 1
			If $Pause = 1 Then
				GUICtrlSetData($ButtonPause, 'Proceed')
				While 1
					If $Pause = 0 Then
						GUICtrlSetData($ButtonPause, $DataButtonPause)
						ExitLoop
					EndIf
					If $ExitFunc = 1 Then
						GUICtrlSetData($ButtonPause, $DataButtonPause)
						ExitLoop
					EndIf
					Sleep(100)
				WEnd
			EndIf
			If $ExitFunc = 1 Then
				GUICtrlSetData($ProgressBar, '')
				Return 6
			EndIf
			Select
				Case $flag = 1
					Select
						Case $FileCopy = 0
							If FileExists($dirname & StringReplace($result[$r], $ArrayFileCopy[$ar][0], '', 1)) Then
								$filenamestring = StringRegExpReplace($dirname & StringReplace($result[$r], $ArrayFileCopy[$ar][0], '', 1), '.*\\', '')
								$pathreplace = StringReplace($dirname & StringReplace($result[$r], $ArrayFileCopy[$ar][0], '', 1), $filenamestring, '', -1)
								$filedestname = $pathreplace & @SEC & @MSEC & '_' & $filenamestring
							Else
								$filedestname = $dirname & StringReplace($result[$r], $ArrayFileCopy[$ar][0], '', 1)
							EndIf
						Case $FileCopy = 1
							$filedestname = $dirname & StringReplace($result[$r], $ArrayFileCopy[$ar][0], '', 1)
							If FileExists($filedestname) Then FileSetAttrib($filedestname, '-RSH')
					EndSelect
				Case $flag = 2
					If Not $f_s = 0 Then
						Select
							Case $FileCopy = 0
								If FileExists($ArrayFileCopy[$ar][1] & '\' & StringRegExpReplace($result[$r], '.*\\', '')) Then
									$filenamestring = StringRegExpReplace($result[$r], '.*\\', '')
									$pathreplace = StringReplace($ArrayFileCopy[$ar][1], $filenamestring, '', -1)
									$filedestname = $pathreplace & '\' & @SEC & @MSEC & '_' & $filenamestring
								Else
									$filedestname = $ArrayFileCopy[$ar][1] & '\' & StringRegExpReplace($result[$r], '.*\\', '')
								EndIf
							Case $FileCopy = 1
								$filedestname = $ArrayFileCopy[$ar][1] & '\' & StringRegExpReplace($result[$r], '.*\\', '')
								If FileExists($filedestname) Then FileSetAttrib($filedestname, '-RSH')
						EndSelect
					Else
						Select
							Case $CopyArray = 1
								$filedestname = $ArrayFileCopy[$ar][1] & '\' & StringRegExpReplace($result[$r], '.*\\', '')
							Case $CopyArray = 0
								$filedestname = $ArrayFileCopy[$ar][1]
						EndSelect
					EndIf
			EndSelect

			$hFile = FileOpen($result[$r], 16)
			If $hFile = -1 Then
				$z += 1
				ContinueLoop
			EndIf
			$folderdestname = FileOpen($filedestname, 2 + 8 + 16)
			If $folderdestname = -1 Then
				FileClose($hFile)
				$x += 1
				ContinueLoop
			EndIf
			While 1
				If $Pause = 1 Then
					GUICtrlSetData($ButtonPause, 'Proceed')
					While 1
						If $Pause = 0 Then
							GUICtrlSetData($ButtonPause, $DataButtonPause)
							ExitLoop
						EndIf
						If $ExitFunc = 1 Then
							GUICtrlSetData($ButtonPause, $DataButtonPause)
							ExitLoop
						EndIf
						Sleep(100)
					WEnd
				EndIf
				If $ExitFunc = 1 Then
					GUICtrlSetData($ProgressBar, '')
					FileClose($hFile)
					FileClose($folderdestname)
					FileDelete($filedestname)
					Return 6
				EndIf
				$sChars = FileRead($hFile, $s)
				If @error = -1 Then
					ExitLoop
				ElseIf @error = 1 Then
					$z += 1
					ExitLoop
				EndIf
				$file_w = FileWrite($folderdestname, $sChars)
				If $file_w = 0 Then
					$x += 1
					ExitLoop
				EndIf
				If $b = $step * $a Then
					GUICtrlSetData($ProgressBar, $a)
					$a += 1
				EndIf
				$b += 1
			WEnd
			FileClose($hFile)
			FileClose($folderdestname)
			$attrib = FileGetAttrib($result[$r])
			FileSetAttrib($filedestname, $attrib)
		Next
		$emptyfolder = _FO_SearchEmptyFolders($ArrayFileCopy[$ar][0], 1)
		If Not @error Then
			For $i = 1 To $emptyfolder[0]
				$pathdestreplace = StringReplace($emptyfolder[$i], '\', '', -1)
				$emptyfoldername = $dirname & StringReplace($pathdestreplace, $ArrayFileCopy[$ar][0], '', 1)
				DirCreate($emptyfoldername)
			Next
		EndIf
	Next
	If $z = 0 And $x = 0 And $y = 0 Then
		If $guimsg = 1 Then
			GUIRegisterMsg(0x0111, '')
		EndIf
		GUICtrlSetData($ProgressBar, 100)
		Sleep(1000)
		GUICtrlSetData($ProgressBar, '')
		Return 0
	ElseIf $y = UBound($ArrayFileCopy) Or $x = UBound($result) Or $z = UBound($result) Or $null = UBound($ArrayFileCopy) Then
		If $guimsg = 1 Then
			GUIRegisterMsg(0x0111, '')
		EndIf
		Return 4
	Else
		If $guimsg = 1 Then
			GUIRegisterMsg(0x0111, '')
		EndIf
		GUICtrlSetData($ProgressBar, 100)
		Sleep(1000)
		GUICtrlSetData($ProgressBar, '')
		Return 5
	EndIf
EndFunc   ;==>_CopyDirCopyFile

Func WM_COMMAND_Copy_Gui($hWnd, $Msg, $wParam, $lParam)
	Local $nNotifyCode = BitShift($wParam, 16)
	Local $nID = BitAND($wParam, 0xFFFF)
	Switch $nNotifyCode
		Case 0
			Switch $nID
				Case $ButtonStop
					$ExitFunc = 1
					GUIRegisterMsg(0x0111, '')
				Case $ButtonPause
					If $Pause = 0 Then
						$Pause = 1
					Else
						$Pause = 0
					EndIf
			EndSwitch
	EndSwitch
	Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_COMMAND_Copy_Guii
 

obeyme

Новичок
Сообщения
71
Репутация
0
Отличный пример! :laugh: Спасибо! :IL_AutoIt_1:
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
небольшое изменение (оптимизация)
1. кнопки выхода и паузы можно назначать независимо. то есть на месте не нужной оставить пустое значение - ""
2.если не будут использоваться вообще никакие кнопки в функции, то функция
Код:
GUIRegisterMsg(0x0111, 'WM_COMMAND_Copy_Gui')

не будет регистрироваться(включаться). что позволит не засорять данными память
смотри измененную функцию в сообщении 24
http://autoit-script.ru/index.php/topic,13191.msg85647.html#msg85647
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
сделаны изменения: учтен момент, когда может поступить пустой массив или с некоторыми пустыми строками.
из-за того, что найдены баги во включаемых функциях была установлена дополнительная обработка ошибок
исправленные варианты функции в первом сообщении темы

http://autoit-script.ru/index.php/topic,13191.msg84334.html#msg84334


Добавлено:
Сообщение автоматически объединено:

чтобы корректно работала функция следует обновить UDF FileOperations.au3 в папке
C:\Program Files\AutoIt3\Include
спасибо AZJIO за обновление FileOperations.au3
смотри вложение
или здесь http://azjio.ucoz.ru/publ/skripty_autoit3/funkcii/filesearch/11-1-0-33
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
небольшая поправка в функции. была найдена ошибка подсчета размера файлов при выборе нескольких файлов для копирования через диалог открытия файлов
Код:
FileOpenDialog

из-за этой ошибки не было отображения прогресса копирования.
измененная функция в первом сообщении темы (второй вариант)
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
небольшая поправка в функции.
почему то сразу не заметил ошибку
код в первом сообщении. второй вариант. просьба к тем, кто смотрит тему сделать тест копирования файлов и папок из второго варианта.
первый вариант не исправлялся, так как ошибок не нашел
 

Mancoffee

Свет проталкивает тьму ...
Сообщения
86
Репутация
1
joiner
А в чём заключается ошибка?
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
если данные получаются не из массива, а функциями выбора папки (копирование папки в другую папку), была ошибка подсчета размера файлов..
при использовании массива эта ошибка не проявлялась...
это касается второго варианта из первого сообщения.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
сделал небольшое , можно назвать, исправление в функции:
при выборе параметра -
Код:
$FileCopy = 1;перезаписывать файл в месте назначения

функция перезаписывала исходный файл, если он копировался в ту же папку.
к примеру с рабочего стола на рабочий стол.
добавлена проверка путей
Код:
If $ArrayFileCopy[$ar][1] & '\' = $path[1] & $path[2] Then
	$x += 1
	ContinueLoop
EndIf

решающего значение это изменение не имеет. сделано для того, если пользователь ошибся с выбором пути назначения, чтобы не был испорчен исходный файл. вобщем, ради безопасности :smile:
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
функция изменена.
изменено создание имен копий файлов
оптимизация работы функции.
добавлен параметр
смотри первое сообщение темы
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Хорошая работа, но все портит то, что копирование происходит в одном потоке с основной программой. Как ни крути, а это будет подвешивать GUI. А если уменьшить размер буфера, то время копирования сильно увеличится.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
да, подвешивает. не часто но бывает . как обойти в виду однопоточности языка?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
joiner сказал(а):
как обойти в виду однопоточности языка?

Я вижу только два варианта:

- написать dll, в котором, собственно, и будет реализован весь процесс копирования (я так и поступил с Copy UDF)
- запускать второй процесс, а информацию о ходе копирования передовать посредством WM_COPYDATA
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
если библиотеку писать, то как учесть взаимодействие между функцией и элементом прогресса.
в одной программе все понятно.
а если из библиотеки, то нужно будет организовать передачу данных этапа копирования в окно программы. что то я смутно это представляю. или тут тоже будет типа WM_COPYDATA. только между библиотекой (грубо говоря) и окном программы, которая вызывает функцию из библиотеки?

хотя вариант с экзе мне будет проще сделать, так как я другого языка не знаю, но запуск дополнительного процесса как то не очень эффективно
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Yashied [?]
- запускать второй процесс, а информацию о ходе копирования передавать посредством WM_COPYDATA
я сделал по другому. использовал показанный тобою способ интеракции между скриптами - http://autoit-script.ru/index.php/topic,2733.0.html
здесь готовые экзешники и исходники http://autoit-script.ru/index.php?action=downloads;sa=view;down=357
это пока тестовая версия.
запускать только - Пример.exe. он получает данные и запускает файл _CopyDirCopyFile.exe. который и копирует. так же можно ставить на паузу или отменять копирование. полоса прогресса тоже прикручена к реальному процессу копирования.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Доделал код обмена данными между скриптами для копирования файлов и папок.
смотри первое сообщение темы , вложение _CopyDirCopyFile + обмен
конечно, это уже не включаемая функция, но в принципе можно использовать в любой конфигурации окна
 
Верх