Что нового

[Файловая система] Утилита для копирования файлов и папок

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
AutoIt: 3.3.8.1

Категория: Вспомогательные функции, Файловая система

Описание: Программа для копирования файлов и папок по типу системного копирования:
Для копирования файлов в системе мы выделяем файлы и в контекстном меню выбираем пункт "Копировать" или жмем на клавиатуре CTRL-C. При этом система направляет в буфер обмена пути к выделенным объектам (папкам, файлам). Программа считывает буфер обмена и появляется окно, в котором мы можем выбрать путь сохранения и указать, нужна ли перезапись.
Копирование происходит без уведомлений. Если файл или папка заняты процессом или нет прав, то программа пропускает их и копирует остальные

Файл: AU3,EXE

Снимок:


Источник: autoit-script.ru
Автор(ы): joiner
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
сделал небольшое изменение в коде слежения за буфером обмена. точнее, слежение идет за появлением скрытого окна CLIPBRDWNDCLASS (либо оно постоянно есть. точно не исследовал)
Код:
$clip_owner = _ClipBoard_GetOwner()
	$class_win = _WinAPI_GetClassName($clip_owner)
	If $class_win = 'CLIPBRDWNDCLASS' Then

заметил, что при выделении и нажатии пункта "копировать" в контекстном меню или при нажатии клавиш Ctrl-C владельцем буфера становится это окно. когда это происходит, тогда и срабатывает код моей программы. потому что в этом случае можно быть уверенным, что было передача путей к файлам(папкам), которые пользователь собирается копировать, в буфер обмена. Этим самым я решил вопрос копирования в сетевые папки и наоборот.
если есть возможность, просьба протестировать программу.
как и написано было в первом сообщении программа копирует файлы "без тормозов" :smile:

PS . сама функция копирования написана мною. http://autoit-script.ru/index.php/topic,13191.0.html
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
Имхо, как то не очень "экологично" следить за буфером обмена и что то там с ним делать. Добавьте вашу программу в меню, пусть будет "копировать с помощью вашей программы"
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Возможно стоит отображать информацию о том откуда и куда копируется ?
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
inververs
я думал об этом вначале, тогда нужен будет другой подход - получать пути к выделенным файлам и папкам. на форуме есть варианты, но мне они так же кажутся не очень "экологичными" :smile:. хотя, возможно, я ошибаюсь. еще раз просмотрю примеры.
в этой программе я не совсем слежу за буфером обмена, я слежу за появлением системного владельца буфера обмена. что именно не "экологичного" ты в этом увидел?
gregaz
возможно стоит, но это опции, которые каждый может добавить. они не несут решающего значения. хотя ради большей информативности стоит..хотел сделать по типу окна копирования в семерке - изменяющийся размер для показа дополнительной информации. но честно сказать, я всегда был холоден к графическим опциям. важен функционал.


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

по сути сама система передает эти данные через буфер обмена и кто то системный ( :smile: ) их считывает..ну я тоже их считываю
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
пришлось делать повторные исправления . здесь http://autoit-script.ru/index.php/topic,15194.msg95091.html#msg95091 проблема, которую решал. насколько удачно - не знаю. пока работает
буду признателен за тесты и советы
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
программа изменена. добавлена функция отчета если некоторые файлы не скопированы.
использованы функции предотвращения мерцания элементов окна http://autoit-script.ru/index.php/topic,5632.0.html
исправлены мелкие недочеты . если есть у кого возможность, просьба протестировать
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
joiner
На WinXP не перехватывает копирование. Посмотри иконку.
_ConvertFileSize можно заменить на _FO_ShortFileSize
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
AZJIO [?]
На WinXP не перехватывает копирование
нужно отследить класс окна , которое является владельцем буфера обмена..у меня ХР под рукой нет.
в первом сообщении я привел код, который отслеживает появление этого окна.
насчет иконки не понял

_ConvertFileSize можно заменить на _FO_ShortFileSize
да, я хотел задать тебе вопрос по функции _ConvertFileSize . в некоторых случаях она показывает слишком разные объемы. это в основном касается папок со вложенными папками и файлами..порядка 20мб разница бывала, чем показывала система..не критично, конечно. я заменю ее на другую - _FO_ShortFileSize
спасибо за тестирование


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

_FO_ShortFileSize показывает точные данные об объеме объекта..проверил :smile:
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
joiner
Разница есть. Стандартная функция Windows работает чуть медленнее и отбрасывает не округляя, то есть 3.55 будет как 3.5, а вообще то должно округлится и показать 3.6, ну видимо откинуть цифры проще и точность приемлимая. А _ConvertFileSize как бы высчитывыает так что 1024 приравнивается к 1000, чтобы после 999 Мб был 1 Гб, а не 1000 Мб и т.д, т.е. применяется коэффициент уменьшающий, отсюда и неточность.

насчет иконки не понял
иконка в трее как то выглядит коряво. При трансформации иконки 253х199 в правильный квадрат 16х16 происходит потеря сглаживания с полупрозрачными пикселами, обычное вычисление среднего цвета пиксела на основе нескольких. Уж лучше трансформировать в редакторе иконок, чем позволить делать это "проводнику".
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
насчет иконки. я все писал в семерке. все сглажено.

AZJIO [?]
Уж лучше трансформировать в редакторе иконок
что за редактор?. я скачал картинку и в фотошопе убрал белый фон. потом конвертировал в иконку.
что насчет владельца буфера обмена. ты пробовал код определения на ХР?
а вообще огромное спасибо тебе за твою библиотеку..без нее я бы долго карячился с функцией копирования :smile:
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
joiner [?]
ты пробовал код определения на ХР?
тот же CLIPBRDWNDCLASS выдал. Всё, понял, перечитал твою инструкцию. Надо было Ctrl+C, а я перетащить-бросить использовал.

и в фотошопе убрал белый фон
не должно там быть белого фона. И фотошоп может открыл как растр? Там же пакетная иконка, т.е. в ней 4 иконки с размерами 16х16, 32х32, 48х48, 256х256, популярные размеры.

что за редактор?
из платных ArtIcons Pro, IconWorkshop, из бесплатных - старая версия IcoFX.

Кстати, при использовании обновления лейблов у меня сильно тормозило процесс при поиске файлов в утилите поиска дубликатов Search_duplicates и я хотел сделать обновление не по файлово, а по мегабайтно. Например много файлов по 1 кб будут копироваться так быстро, что следить их в лейбле не реально, а время на перерисовку они потребляют (у меня поиск 5 минут при показе в лейбл и 2 минуты без показа). В итоге делаешь счётчик, в который прибавляется размер файла, как только счётчик достиг 10 Мб, то показывает текущий файл, а счётчик сбрасывается в 0. В итоге скорость копирования с флешки и с HDD может быть 10-60Мб в сек, это значит что 1-6 раз в секунду будет обновляться лейбл.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
AZJIO [?]
не должно там быть белого фона. И фотошоп может открыл как растр? Там же пакетная иконка
я скачал обычный .jpg с инета и в фотошопе очистил фон, а потом через онлайнконвертер сделал иконку
насчет обновления лэйбла копируемого файла, так я хотел вообще отказаться от этой строки..не вижу особого смысла в ней. файлы мелькают..в глазах рябит :smile:
оставил как есть. исходники каждый может поправить под себя
я делал более редкое обновление скопированного объема. тоже, в принципе, снижает потребление ресурсов. ставил в одно условие с обновлением процентов в строке прогресса.
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
joiner
Посмотри как выглядит в разных видах отображения в проводнике. Верхний ряд - твой вариант иконки.


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

joiner

Теоретически у тебя есть возможность расширить особенности программы. Пока она просто копирует файлы, как это делает стандартная опция, ну кроме "сделать паузу".

1. Вместо трёх кнопок можно оставить одну с названием "Выбрать место назначения", а то первый вопрос возникает как наживать "старт" если "куда" не выбрано. При начале копирования кнопка изменяется на "пауза". При нажатии на "Пауза" кнопка изменяется на "Продолжить". В качестве "Отмена" достаточно "Закрыть" окно.
2. Добавить кнопку "Опции" и добавить возможность выбрать тип файлов, которые нужно скопировать (Маска, триггер "Кроме указанных в маске"). Добавить опцию "Копировать игнорируя структуру каталогов", что позволит например некоторый тип файлов скопировать в кучу (всё в одну папку) для просмотра.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 338
Репутация
574
сделано небольшое изменение в функции копирования http://autoit-script.ru/index.php/topic,13191.new.html#new
файлы в этой теме тоже перезалиты
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1 575
Репутация
335
Более правильно, конечно было бы сделать через Copy Hook, я пытался написать нечто подобное, но у меня не вышло..

http://msdn.microsoft.com/en-us/library/bb776048(v=vs.85).aspx
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 473
Репутация
2 403
Пример как это можно сделать более корректно:

Код:
#include <ClipBoard.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>

OnAutoItExitRegister('_OnExit')

$hGUI = GUICreate('*_Clipboard_*')
$hCBViewer = _ClipBoard_SetViewer($hGUI)

GUIRegisterMsg($WM_CHANGECBCHAIN, 'WM_CHANGECBCHAIN')
GUIRegisterMsg($WM_DRAWCLIPBOARD, 'WM_DRAWCLIPBOARD')

While 1
	Sleep(100)
WEnd

Func _OnExit()
	_ClipBoard_ChangeChain($hGUI, $hCBViewer)
EndFunc

Func _CopyGUI()
	AdlibUnRegister('_CopyGUI')
	
	MsgBox(64, 'Title', 'Copy: ' & @LF & ClipGet())
EndFunc

Func WM_CHANGECBCHAIN($hWnd, $iMsg, $iwParam, $ilParam)
	; If the next window is closing, repair the chain
	If $iwParam = $hCBViewer Then
		$hCBViewer = $ilParam
		; Otherwise pass the message to the next viewer
	ElseIf $hCBViewer <> 0 Then
		_SendMessage($hCBViewer, $WM_CHANGECBCHAIN, $iwParam, $ilParam, 0, 'hwnd', 'hwnd')
	EndIf
EndFunc

Func WM_DRAWCLIPBOARD($hWnd, $iMsg, $iwParam, $ilParam)
	If _ClipBoard_GetDropEffect() = 'DROPEFFECT_COPY' Then
		AdlibRegister('_CopyGUI', 100)
	EndIf
	
	; Pass the message to the next viewer
	If $hCBViewer <> 0 Then
		_SendMessage($hCBViewer, $WM_DRAWCLIPBOARD, $iwParam, $ilParam)
	EndIf
EndFunc

Func _ClipBoard_GetDropEffect()
	Local $sRetDropEffect, $iFormat, $hMemory, $hDropEffect, $tDropEffect, $iDropEffect
	Local $hClipBoard_GUI = GUICreate('_ClipBoard_GetDropEffect')
	
	Local $CF_PREFERREDDROPEFFECT = 0 ; not constant, changes value
	Local Const $DROPEFFECT_NONE = 0 ; Drop target cannot accept the data.
	Local Const $DROPEFFECT_COPY = 1 ; Drop results in a copy. The original data is untouched by the drag source.
	Local Const $DROPEFFECT_MOVE = 2 ; Drag source should remove the data.
	Local Const $DROPEFFECT_LINK = 4 ; Drag source should create a link to the original data.
	
	; Open the clipboard
	If Not _ClipBoard_Open($hClipBoard_GUI) Then Return SetError(1, GUIDelete($hClipBoard_GUI), '_ClipBoard_Open failed')
	
	Do
		$iFormat = _ClipBoard_EnumFormats($iFormat)
		If $iFormat <> 0 And _ClipBoard_FormatStr($iFormat) == 'Preferred DropEffect' Then $CF_PREFERREDDROPEFFECT = $iFormat
	Until $iFormat = 0
	
	; if clipboard contains cut or copied files
	If _ClipBoard_IsFormatAvailable($CF_HDROP) Then
		$hMemory = _ClipBoard_GetDataEx($CF_HDROP) ; get handle to clipboard files
		$hDropEffect = _ClipBoard_GetDataEx($CF_PREFERREDDROPEFFECT) ; get handle to DropEffect enumeration

		If $hMemory = 0 Then Return SetError(2, GUIDelete($hClipBoard_GUI), _
			'_ClipBoard_GetDataEx failed to get handle to clipboard files')
		If $hDropEffect = 0 Then Return SetError(3, GUIDelete($hClipBoard_GUI), _
			'_ClipBoard_GetDataEx failed to get handle to DropEffect enumeration')
		
		$tDropEffect = DllStructCreate('dword', $hDropEffect)
		$iDropEffect = DllStructGetData($tDropEffect, 1)

		If BitAND($iDropEffect, $DROPEFFECT_MOVE) = $DROPEFFECT_MOVE Then
			$sRetDropEffect = 'DROPEFFECT_MOVE'
		ElseIf BitAND($iDropEffect, $DROPEFFECT_COPY) = $DROPEFFECT_COPY Then
			$sRetDropEffect = 'DROPEFFECT_COPY'
		ElseIf BitAND($iDropEffect, $DROPEFFECT_LINK) = $DROPEFFECT_LINK Then
			$sRetDropEffect = 'DROPEFFECT_LINK'
		ElseIf $iDropEffect = $DROPEFFECT_NONE Then
			$sRetDropEffect = 'DROPEFFECT_NONE'
		EndIf
	Else
		$sRetDropEffect = 'Error - ClipBoard does not contain cut or copied files'
	EndIf
	
	; Close the clipboard
	_ClipBoard_Close()
	
	GUIDelete($hClipBoard_GUI)
	
	If $sRetDropEffect = '' Then Return SetError(2, 0, 'Error - Probably last Effect was reset (files deleted?)')
	Return $sRetDropEffect
EndFunc
 
Верх