Что нового

Автоматическое копирование с USB

MusicMan_08

Новичок
Сообщения
28
Репутация
0
Добрый день, нашел в сети скрипт, который позволяет сделать бекап с вставленного USB, но у меня почему-то не запускается...
Может быть кто-нибудь знает, как допилить его - чтобы была возможность назвать директорию, куда будет происходить копирование?
Код:
Dim $DBT_DEVICEARRIVAL = "0x00008000"
Dim $DBT_DEVICECOMPLETEREMOVAL = "0x00008004"
Dim $USB_ATTENTION = "0x00000007"
Dim $WM_DEVICECHANGE = 0x0219
Dim $Drives
Dim $Drive_Type = "ALL"  ; Set to ALL because some USB Drives are detected as Fixed Disks, and we don't want to miss those
Dim $WATCH = False
Dim $MyDrive = "STUFF"

;Get Initial List of Drives to Check Against
UpdateDrives()
;Setup The GUI to watch for the DeviceChange Event
GUICreate("")
GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange")
Func DeviceChange($hWndGUI, $MsgID, $WParam, $LParam)
    Switch $WParam
        Case $USB_ATTENTION
        ; This only happens when USB drives are inserted, so I use it to tell the difference between these and CDROMs
            $WATCH = True
        Case $DBT_DEVICECOMPLETEREMOVAL
        ; Whenever a Drive is Removed, Update the Drive List
            UpdateDrives()
        Case $DBT_DEVICEARRIVAL
        ; A drive was inserted
        ; Use $WATCH to tell if this was a CDROM or USB
        ; $WATCH = True, USB
        ; $WATCH = False, CDROM
            If $WATCH = True Then
            ; New USB Drive Was Detected, Time to Find it's Letter
                $New = FindNewDrive(); $New now has the Drive Letter of our New Drive, so USE IT!!!
                $Label = DriveGetLabel($New)
                If $Label == $MyDrive Then
                    MsgBox(4096, "Info", "My Drive has been Inserted, Backup My Files!")
                EndIf
            ; Now Reset Drive List so more insertions can also be detected accurately
                UpdateDrives()
            EndIf
    EndSwitch
EndFunc  ;==>DeviceChange

; This just jumps through the new Drive List, comparing them until it finds the entry that is in the new one that isn't in the old one
Func FindNewDrive()
    $Temp = DriveGetDrive( "REMOVABLE" )
    For $i = 1 to $Temp[0]
        $Old = False
        For $j = 1 to $DRIVES[0]
            If $DRIVES[$j] == $Temp[$i] Then $Old = True
        Next
        If $Old == False Then Return $Temp[$i]  
    Next
EndFunc  ;==>FindNewDrive

; Just to keep things neat, and so if Variables Ever Change, this makes updating easier
Func UpdateDrives()
    $Drives = DriveGetDrive( $Drive_Type )
EndFunc  ;==>UpdateDrives

; Main Loop to Keep the Program Open
; No Real Way of ending this program, except for just killing the process
; Which is what I want, an always on backup for my drive every time I insert it
While 1
    $GuiMsg = GUIGetMsg()
; This is needed because the watch event above not only triggers before a USB Drive is inserted/removed,
; but also AFTER insertion too, and if not reset, a subsequent CD insertion will trigger it again.
; So, every second, we reset $WATCH, to keep things clean
    Sleep (1000)
    $WATCH = False
WEnd




Версия AutoIt: v3.3.10.2

Описание:

Примечания:
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
MusicMan_08, вставь код AutoIt в соответствующие теги
 

Ganibal95

GreenBytes
Сообщения
877
Репутация
240
MusicMan_08
Вообще не вижу в нем копирования, мне кажется легче написать код с 0, дабы разбирать этот бред.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
MusicMan_08

Код:
#include <WinAPIEx.au3>
#include <APIConstants.au3>

Opt('MustDeclareVars', 1)
Opt('TrayAutoPause', 0)

Global Const $DBT_DEVICEARRIVAL = 0x00008000
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x00008004
Global Const $DBT_DEVTYP_VOLUME = 0x00000002

Global $hForm = GUICreate('')
Global $Drives, $Volume = _WinAPI_GetLogicalDrives()
Global $Device = 1

GUIRegisterMsg($WM_DEVICECHANGE, 'WM_DEVICECHANGE')

While 1
	Sleep(100)
	If $Device Then
		$Drives = _GetDriveLetter($Volume)
		$Device = 0
		$Volume = 0
		For $j = 1 To $Drives[0]
			_USBCheck($Drives[$j])
		Next
	EndIf
WEnd

Func _USBCheck($sVolume)

	Local $hDrive, $tData, $iBus, $iRes, $Fs

	$iBus = _WinAPI_GetDriveBusType($sVolume)
	Switch $iBus
		Case $DRIVE_BUS_TYPE_USB
			$hDrive = _WinAPI_CreateFileEx('\\.\' & $sVolume, 3, 0, 0)
			If Not $hDrive Then
				Return
			EndIf
			$tData = DllStructCreate('dword DeviceType;ulong DeviceNumber;ulong PartitionNumber')
			$iRes = _WinAPI_DeviceIoControl($hDrive, $IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, DllStructGetPtr($tData), DllStructGetSize($tData))
			_WinAPI_CloseHandle($hDrive)
			If (Not $iRes) Or (Not (DllStructGetData($tData, 'DeviceType') = 7)) Then
				Return
			EndIf
		Case Else
			Return
	EndSwitch

	If $sVolume = 'E:' Then ; проверка буквы диска
		Local $sPath = FileSelectFolder('Выберите папку', '', 3, @DesktopDir) ; выбор папки
		DirCopy($sVolume & '\DCIM', $sPath, 1) ; копирование нужной папки по в выбранную папку
	EndIf

	ConsoleWrite($sVolume & @CR)
EndFunc   ;==>_USBCheck

Func _GetDriveLetter($iMask)

	Local $Drive[27] = [0]

	If $iMask Then
		For $i = 0 To 25
			If BitAND(BitShift($iMask, $i), 1) Then
				$Drive[$Drive[0] + 1] = Chr(65 + $i) & ':'
				$Drive[0] += 1
			EndIf
		Next
	EndIf
	ReDim $Drive[$Drive[0] + 1]
	Return $Drive
EndFunc   ;==>_GetDriveLetter

Func WM_DEVICECHANGE($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hForm
			Switch $wParam
				Case $DBT_DEVICEARRIVAL, $DBT_DEVICEREMOVECOMPLETE

					Local $tDBV = DllStructCreate('dword Size;dword DeviceType;dword Reserved;dword Mask;ushort Flags', $lParam)
					Local $Type = DllStructGetData($tDBV, 'DeviceType')
					Local $Item

					Switch $Type
						Case $DBT_DEVTYP_VOLUME
							If Not DllStructGetData($tDBV, 'Flags') Then
								Switch $wParam
									Case $DBT_DEVICEARRIVAL
										$Volume = BitOR($Volume, DllStructGetData($tDBV, 'Mask'))
										$Device = 1
									Case Else

								EndSwitch
							EndIf
						Case Else

					EndSwitch
			EndSwitch
	EndSwitch
	Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_DEVICECHANGE
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
WSWR
Огромное спасибо! Возникло несколько вопросов:
1) Я вставляю одновременно 4 флешки (в скрипте прописываю буквы для этих флешек) и копирование начинается с одной, потом с другой и т.д. по очереди. Можно ли, чтобы копирование шло одновременно и при выборе путей сохранения было очевидно, какую флешку в какой путь я сохраняю?
2) Как организовать проверку, что копирование прошло удачно или неудачно?
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
MusicMan_08
На счет одновременного копирования посмотри эту UDF:
http://autoit-script.ru/index.php/topic,3049.0.html
Там примеры хорошие

Можно свое окно GUI создать, и в нем можно четыре прогресс-бара сделать, с подписями, что и куда копируется.
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
Дело в том, что имеется хаб на 4 флешки - вставляем последовательно, когда вставишь - определяются все 4 разом, так что пути сохранения нужно ввести сразу для 4-х флешок, чтобы не отвлекаться потом на каждую флешку... Да и процесс может затянуться на долго и сидеть ждать, когда одна откопируется, потом указать путь для следующей очень муторно.
Процесс представляю примерно так: вставляешь 4 флешки, выскакивает сообщение куда сохранить флешку 1 - выбрал, куда сохранить флешку 2 - выбрал и т. Пошло копирование с прогресс баром, по окончании какое-нибудь уведомление.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
MusicMan_08

Как-то так:

Код:
#include <WinAPIEx.au3>
#include <APIConstants.au3>

Opt('MustDeclareVars', 1)
Opt('TrayAutoPause', 0)

Global Const $DBT_DEVICEARRIVAL = 0x00008000
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x00008004
Global Const $DBT_DEVTYP_VOLUME = 0x00000002

Global $hForm = GUICreate('')
Global $Drives, $Volume = _WinAPI_GetLogicalDrives()
Global $Device = 1
Global $aK[5]

GUIRegisterMsg($WM_DEVICECHANGE, 'WM_DEVICECHANGE')

While 1
	Sleep(100)
	If $Device Then
		$Drives = _GetDriveLetter($Volume)
		$Device = 0
		$Volume = 0
		For $j = 1 To $Drives[0]
			_USBCheck($Drives[$j])
		Next
	EndIf
WEnd

Func _USBCheck($sVolume)

	Local $hDrive, $tData, $iBus, $iRes, $Fs

	$iBus = _WinAPI_GetDriveBusType($sVolume)
	Switch $iBus
		Case $DRIVE_BUS_TYPE_USB
			$hDrive = _WinAPI_CreateFileEx('\\.\' & $sVolume, 3, 0, 0)
			If Not $hDrive Then
				Return
			EndIf
			$tData = DllStructCreate('dword DeviceType;ulong DeviceNumber;ulong PartitionNumber')
			$iRes = _WinAPI_DeviceIoControl($hDrive, $IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, DllStructGetPtr($tData), DllStructGetSize($tData))
			_WinAPI_CloseHandle($hDrive)
			If (Not $iRes) Or (Not (DllStructGetData($tData, 'DeviceType') = 7)) Then
				Return
			EndIf
		Case Else
			Return
	EndSwitch

	$aK[0] += 1
	$aK[$aK[0]] = $sVolume

	ConsoleWrite($sVolume & @CR)

	If $aK[0] = 4 Then
		Local $aPath[4]
		$aPath[0] = FileSelectFolder('Выберите папку', '', 3, @DesktopDir) ; выбор папки
		$aPath[1] = FileSelectFolder('Выберите папку', '', 3, @DesktopDir) ; выбор папки
		$aPath[2] = FileSelectFolder('Выберите папку', '', 3, @DesktopDir) ; выбор папки
		$aPath[3] = FileSelectFolder('Выберите папку', '', 3, @DesktopDir) ; выбор папки
		DirCopy($aK[1] & '\DCIM', $aPath[0], 1) ; копирование нужной папки по в выбранную папку
		DirCopy($aK[2] & '\DCIM', $aPath[1], 1) ; копирование нужной папки по в выбранную папку
		DirCopy($aK[3] & '\DCIM', $aPath[2], 1) ; копирование нужной папки по в выбранную папку
		DirCopy($aK[4] & '\DCIM', $aPath[3], 1) ; копирование нужной папки по в выбранную папку
		MsgBox(0, 'Результат', 'Копирование закончено!')
	EndIf

EndFunc   ;==>_USBCheck

Func _GetDriveLetter($iMask)

	Local $Drive[27] = [0]

	If $iMask Then
		For $i = 0 To 25
			If BitAND(BitShift($iMask, $i), 1) Then
				$Drive[$Drive[0] + 1] = Chr(65 + $i) & ':'
				$Drive[0] += 1
			EndIf
		Next
	EndIf
	ReDim $Drive[$Drive[0] + 1]
	Return $Drive
EndFunc   ;==>_GetDriveLetter

Func WM_DEVICECHANGE($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hForm
			Switch $wParam
				Case $DBT_DEVICEARRIVAL, $DBT_DEVICEREMOVECOMPLETE

					Local $tDBV = DllStructCreate('dword Size;dword DeviceType;dword Reserved;dword Mask;ushort Flags', $lParam)
					Local $Type = DllStructGetData($tDBV, 'DeviceType')
					Local $Item

					Switch $Type
						Case $DBT_DEVTYP_VOLUME
							If Not DllStructGetData($tDBV, 'Flags') Then
								Switch $wParam
									Case $DBT_DEVICEARRIVAL
										$Volume = BitOR($Volume, DllStructGetData($tDBV, 'Mask'))
										$Device = 1
									Case Else

								EndSwitch
							EndIf
						Case Else

					EndSwitch
			EndSwitch
	EndSwitch
	Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_DEVICECHANGE

Не проверял
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
MusicMan_08 [?]
Да и процесс может затянуться на долго и сидеть ждать, когда одна откопируется, потом указать путь для следующей очень муторно.
могу в свою очередь предложить другую функцию копирования - http://autoit-script.ru/index.php/topic,13191.0.html
какие возможности:
может копировать папки и файлы.
можно передавать в функцию массив путей. то есть составляешь массив откуда - куда четыре раза(к примеру) и функция копирует нужные файлы в нужном направлении.
отображает процесс копирование
сразу можно настроить на перезапись файлов
и т.д.
естественно, ввиду ограничения языка, одновременно не копирует. только последовательно. но при копировании небольшого объема файлов разница будет ничтожна. тем более при одновременном копировании скорость не возрастает. в этом можно убедиться экспериментально. запусти несколько копий системного копирования. увидишь как резко упадет скорость
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
WSWR, joiner
Спасибо за варианты!
Попробую во всем этом разобраться

Ребята, вот этот вариант мне очень подходит (нашел по ссылке от joiner)
Код:
#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

Только вот, если можно - то подскажите пожалуйста как доработать до такого:

+ не надо выбирать откуда копировать, это уже ясно из названия формы (т.е. USB1, USB2...)
+ еще в идеале хотелось бы чтобы по кнопке start возникал путь с пресетами на сохранение файлов (пресет1=С:\folder1;...), ну или сбоку где-нибудь были пресеты сохранения фалов
+ ну и совсем круто было бы, чтобы добавлялась дата к пути сохранения
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
MusicMan_08
ты взял тестовый вариант функции. финальный вариант в первом сообщении под ссылкой "Исходник". За его работу я еще могу поручиться :smile:
насчет отображения имен файлов в окне, то смотри такой пример http://autoit-script.ru/index.php/topic,15135.0.html


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

MusicMan_08
вот пример, как можно сделать. только без автоопределения подключения.
подключаешь все нужные флешки к компу. запускаешь код
копирование будет происходить в общую папку C:\folder. в ней будут созданы подпапки с именами флешек. куда и будут скопированы данные
в окне будет отображаться прогресс копирования в виде полосы, процентов и имен файлов с полным путем копирования
https://cloud.mail.ru/public/a22ab2a581ea/copy_usb.au3
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
Ребята, спасибо за ответы, но это немного не то, что мне надо, я попробовал разные варианты и ссылки, но:
я имею дело с SD картами, которые через переходники вставляются в USB, и имена у этих SD карт всегда разные, т.е привязать имена флешек к коду не видится возможным. SD карты используются на съемках и все время перед съемкой форматируются, все время меняется имя и ID.
Задача человека, который принимает эти SD карты со съемки - !!!в теории!!! вставить карту (USB), ввести номер SD (он на ней наклеен) и получить копию этой SD в папке, которая соответствует номеру SD-шки. То есть, если карта памяти имеет номер 1 - то она должна быть скопирована, к примеру, C:\folder1; если карта памяти номер 2 - то C:\folder2.
Было бы круто, если вставляешь флешку (автоопределение) - выскакивает вопрос куда скопировать - вводишь цифру, и взависимости от нее изменяется путь копирования и копирование начинается. То есть минимум нажатий куда либо, подключить флешку и ввести номер.
Я извиняюсь, если запутал и не рассказал сразу подробности, но я думал это не будет очень важно, а как оказалось подходящих для меня вариантов не оказалось. Самому написать код под это дело для меня пока очень сложно.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
MusicMan_08
В теории можно определять, в какой usb порт вставлена флешка.
Т.е. флешку 1 надо вставить в порт 1, флешку 2 - в порт 2 и т.д.
Соответственно, не придется вводить никакие цифры.
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
Было бы идеально, если бы флешек было 4 штуки, а так у меня их 30. Пронумерованы соответственно от 1 до 30. А USB порта всего 4. Поэтому и ищу решение, чтобы вставить флешку и ответить на вопрос какой на ней номер, и в соответствии с этим копировать в нужную папку...
 

joiner

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

WSWR, про порты это мудрено. проще в окне программы ввести номер флешки. вставил флешку, выскочило окно, ввел номер и нажал старт. все

если копировать большой объем данных, то при одновременном копировании будут тормоза системы. я уже писал это
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
про порты это мудрено. проще в окне программы ввести номер флешки. вставил флешку, выскочило окно, ввел номер и нажал старт. все
Да, как раз вот такой вариант я и искал, наверное моя вина, что не смог объяснить это сразу...
Ну если знающие люди говорят, что материала, который здесь уже достаточно для осуществления поставленной задачи, тогда попробую соединить это в один скрипт, если конечно у меня получится...
 

MaximK

Знающий
Сообщения
33
Репутация
5
Твою задачу я бы разделил на два скрипта
первый скрипт весит в ожидании подключения флешки и при подключении флешки вызывает второй который спрашивает номер флешки и копирует файлы.

Пример скрипта который отслеживает подключение и показывает букву подключеной флешки

Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global Const $DBT_DEVICEARRIVAL = 0x8000 ; Найдено новое устройство
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; Устройство отключено
Global Const $DBT_DEVTYP_VOLUME = 0x00000002 ; Логический диск

$gui = GUICreate('Check flash online')
;GUISetState()
GUIRegisterMsg($WM_DEVICECHANGE,"OnDeviceChange")

Do
Until GUIGetMsg()=-3

Func OnDeviceChange($hWND, $msg, $wParam,$lParam)

    If ($wParam = $DBT_DEVICEARRIVAL) Or ($wParam = $DBT_DEVICEREMOVECOMPLETE) Then
        Local $DEV_BROADCAST_VOLUME = DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
                "ushort dbcvflags", $lParam)
        Local $iDriveType = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvdevicetype")
    Else
        Return $GUI_RUNDEFMSG
    EndIf

    ; Если устройство не является логическим диском, то выход из функции
    If $iDriveType <> $DBT_DEVTYP_VOLUME Then Return $GUI_RUNDEFMSG

    Local $iMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvunitmask")
    $iMask = Log($iMask) / Log(2)

    Local $iDrive = Chr(65 + $iMask) & ":"

    Switch $wParam
        Case $DBT_DEVICEARRIVAL ; обнаружение устройства
            TrayTip("WM_DEVICECHANGE", "Устройство подключено "&$iDrive, 5, 1)

        Case $DBT_DEVICEREMOVECOMPLETE ; отключение устройства
            TrayTip("WM_DEVICECHANGE", "Устройство отключено", 5, 2)
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc

Пример второго скрипта возможно выложу завтра или попробуй переделать приведенные выше
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
MaximK
Очень удобное отображение в трее с названием буквы. Спасибо!
 

joiner

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


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

MusicMan_08
вот набросал тестовый вариант https://cloud.mail.ru/public/a22ab2a581ea/copy_usb.au3
программа не следит постоянно за подключением флешек..
на флешках есть номера - 1,2,3.....и так далее
значит в системе рабочие флешки переименовываем. правой кнопкой мыши на диске - переименовать. имена при форматировании не стираются
подключаем флешки (не важно сколько) к компу и запускаем скрипт.
он найдет все флешки и будет единый прогресс копирования с отображением процентов и путей.
копировать будет на диск С:\Video_usb
В этой папке будут созданы папки с именами(номерами) флешек, а внутри будут папки с именем даты и времени копирования.
в данном случае идея с висящим в ожидании флешек скриптом излишняя.
подключаем флешки, запускаем прогу. скопировалось, повторяем процедуру. два раза клацнуть мышкой это не трудно, но зато будешь понимать что делаешь

если идея понравится то доработаем нюансы
 
Автор
M

MusicMan_08

Новичок
Сообщения
28
Репутация
0
joiner
Флешки, отформатированные с помощью видеокамеры, имеют названия типа "Съемный диск" - и почему-то все имеют ID что-то типа 0000-0000. Не знаю особенности это видеокамеры или еще какие-то особенности, но это факт. Если мы говорим про разные вещи - значит я не понял, что Вы имеете в виду...
За скрипт большое спасибо, копирование происходит и все наглядно - но вылезает несколько ошибок типа "Диск отсутствует, в устройстве нет диска \Device\Harddisk4\DR4", "Ошибка -4". Встречный вопрос, а как я пойму с какой флешки (номер) происходит копирование, к примеру, чтобы отключить/изъять уже скопированные, в скрипте это видно только в пути копирования, который можно успеть прочитать во время прогресс бара?
Вариант MaximK с отслеживанием подключения и показывания буквы подключенной флешки мне кажется классным и информативным, очень хочется его оставить...
 
Верх