Что нового

[Автоматизация] Обработка определённого количества файлов

Tosyk

Новичок
Сообщения
206
Репутация
0
Версия AutoIt: 3.3.6.1

Описание:
Нужен скрипт, который имеет GUI с областью, в которую из Explorer'a кидают файлы (только определённый тип) и кнопкой, при нажатии на которую каждый из добавленных файлов обрабатывается поочерёдно таким образом:
1 - создаётся каталог в папке с исходным файлом, с именем исходного файла *.sds
2 - Mafia2ModelDumper.exe "имя_файла_А.sds" (после обработки *.sds файла образуется несколько *.dae файлов)
3 - mesh2rdm.exe "имя_файла_Х.dae" "имя_файла_А\имя_файла_Х.dae" -flipuv -scale 100 -nopause -rotate 0 180 0 (каждый получившийся *.dae файл из пункта 2 обрабатывается и складывается в папку "имя_файла_А")
Так же нужен прогресс-бар.

Примечания:
я вижу GUI так: небольшое окошко с областью с прокруткой для большого количества файлов, чуть ниже прогресс-бар, чуть ниже две кнопки, конвертировать и закрыть, во время конвертирования кнопка закрыть не активна.
Файлы программы и dll должны быть включены в конечный *.EXE

p.s.: цель моя: научится на примере написанию подобных скриптов, так как сделать их мне нужно огромное количество.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Tosyk
Получилась у меня следующая заготовка для окна:
Код:
#include <WinAPIEx.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <Misc.au3>
#include <Constants.au3>

Opt('TrayMenuMode', 1)

Global $sTitle = 'Test', $iSizeAll = 0, $sExt = '*.au3', _;'*.sds';поменяйте, когда будете проверять.
		$iCountDirs = 0
Dim $aSearch_Dirs[$iCountDirs + 1]

_Singleton(@ScriptName)

$hGui = GUICreate($sTitle, 600, 335, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
GUISetBkColor(0xE0FFFF)

$nInputPath = GUICtrlCreateInput('Перетащите сюда папку или кликните по кнопке справа.', 5, 11, 560, _
		18, $ES_READONLY, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetTip(-1, 'Перетащите сюда папку или кликните по кнопке справа.')

$nButtonPath = GUICtrlCreateButton('...', 570, 10, 25, 20)

$nCheckAll = GUICtrlCreateCheckbox('Снять все', 5, 35, 80, 20)
GUICtrlSetState(-1, BitOR($GUI_CHECKED, $GUI_DISABLE))

$nButtonSearch = GUICtrlCreateButton('Найти', 100, 35, 100, 20)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetTip(-1, 'Найти файлы в выбранной папке')

$nButtonDelAll = GUICtrlCreateButton('Удалить все', 210, 35, 100, 20)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetTip(-1, 'Удалить все файлы из списка.')

For $i = $nButtonPath To $nButtonDelAll
	GUICtrlSetCursor($i, 0)
Next

$nListview = GUICtrlCreateListView('', 5, 60, 590, 235, $GUI_SS_DEFAULT_LISTVIEW, _
		BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES))
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetTip(-1, 'Перетащите сюда файлы для обработки.')
$hListView = GUICtrlGetHandle($nListview)
_GUICtrlListView_AddColumn($hListView, 'Имя файла', 100)
_GUICtrlListView_AddColumn($hListView, 'Путь к папке обработки', 380)
_GUICtrlListView_AddColumn($hListView, 'Размер файлов', 100)

$nProgress = GUICtrlCreateProgress(5, 305, 590, 20)

GUISetState()

_WinAPI_EmptyWorkingSet()

While 1
	$nMsg = GUIGetMsg()

	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $GUI_EVENT_DROPPED
			If @GUI_DropId = $nInputPath Then
				GUICtrlSetData($nInputPath, '')
				If _WinAPI_PathIsDirectory(@GUI_DragFile) Then
					GUICtrlSetData($nInputPath, @GUI_DragFile)
					GUICtrlSetTip($nInputPath, @GUI_DragFile)
					GUICtrlSetState($nButtonSearch, $GUI_ENABLE)
				Else
					GUICtrlSetData($nInputPath, 'Нужно выбрать папку.')
					GUICtrlSetTip($nInputPath, 'Перетащите сюда папку или кликните по кнопке справа.')
					GUICtrlSetState($nButtonSearch, $GUI_DISABLE)
				EndIf
			ElseIf @GUI_DropId = $nListview Then
				_DragFile_ListView(@GUI_DragFile)
			EndIf
		Case $nCheckAll
			If GUICtrlRead($nCheckAll) == $GUI_CHECKED Then
				GUICtrlSetData($nCheckAll, 'Снять все')
				_GUICtrlListView_SetItemChecked($hListView, -1)
			Else
				GUICtrlSetData($nCheckAll, 'Выбрать все')
				_GUICtrlListView_SetItemChecked($hListView, -1, False)
			EndIf
		Case $nButtonDelAll
			_GUICtrlListView_DeleteAllItems($hListView)
			_GUICtrlListView_SetColumn($hListView, 0, 'Имя файла')
			_GUICtrlListView_SetColumn($hListView, 2, 'Размер файлов')
			GUICtrlSetState($nButtonDelAll, $GUI_DISABLE)
			GUICtrlSetState($nCheckAll, BitOR($GUI_CHECKED, $GUI_DISABLE))
			GUICtrlSetData($nProgress, 0)
			GUICtrlSetData($nCheckAll, 'Снять все')
			GUICtrlSetData($nInputPath, 'Перетащите сюда папку или кликните по кнопке справа.')
			GUICtrlSetTip($nInputPath, 'Перетащите сюда папку или кликните по кнопке справа.')
			$iSizeAll = 0
			$iCountDirs = 0
			ReDim $aSearch_Dirs[$iCountDirs + 1]
		Case $nButtonSearch
			_Array_To_ListView()
		Case $nButtonPath
			_Get_Folder()
	EndSwitch
WEnd

Func _Array_To_ListView()
	Local $a_Files, $a_ToListView[1][3], $i_Size, $i_Index, $s_Path

	GUICtrlSetData($nProgress, 0)
	$s_Path = GUICtrlRead($nInputPath)
	If _ArraySearch($aSearch_Dirs, $s_Path) <> -1 Then
		GUICtrlSetData($nInputPath, 'В этой папке уже искали файлы.')
		GUICtrlSetState($nButtonSearch, $GUI_DISABLE)
		Return
	Else
		$iCountDirs += 1
		ReDim $aSearch_Dirs[$iCountDirs + 1]
		$aSearch_Dirs[$iCountDirs] = $s_Path
		$aSearch_Dirs[0] = $iCountDirs
	EndIf

	GUISetState(@SW_DISABLE)
	$a_Files = _FileSearch($s_Path, $sExt, 1)
	If $a_Files[0] Then
		ReDim $a_ToListView[$a_Files[0]][3]
		For $i = 1 To $a_Files[0]
			$a_ToListView[$i - 1][0] = _WinAPI_PathStripPath($a_Files[$i])
			$a_ToListView[$i - 1][1] = _WinAPI_PathRemoveExtension($a_Files[$i])
			$i_Size = FileGetSize($a_Files[$i])
			$a_ToListView[$i - 1][2] = _GetSize($i_Size)
			$iSizeAll += $i_Size
			GUICtrlSetData($nProgress, (100 / $a_Files[0]) * $i)
		Next
		_GUICtrlListView_AddArray($hListView, $a_ToListView)
		$i_Index = _GUICtrlListView_GetItemCount($hListView)
		_GUICtrlListView_SetColumn($hListView, 0, 'Имя файла (' & $i_Index & ')')
		_GUICtrlListView_SetColumn($hListView, 2, 'Всего: ' & _GetSize($iSizeAll))
		_GUICtrlListView_SetItemChecked($hListView, -1)
		GUICtrlSetState($nCheckAll, $GUI_ENABLE)
		GUICtrlSetState($nButtonDelAll, $GUI_ENABLE)
	Else
		GUICtrlSetData($nInputPath, 'В этой папке нет нужных файлов.')
		GUICtrlSetTip($nInputPath, 'Перетащите сюда папку или кликните по кнопке справа.')
	EndIf
	GUICtrlSetState($nButtonSearch, $GUI_DISABLE)
	GUISetState(@SW_ENABLE)
EndFunc   ;==>_Array_To_ListView

Func _DragFile_ListView($s_Path)
	Local $i_Index, $i_Size, $s_File

	If _WinAPI_PathMatchSpec($s_Path, $sExt) Then
		$i_Index = _GUICtrlListView_GetItemCount($hListView)
		$s_File = _WinAPI_PathStripPath($s_Path)
		For $i = 0 To $i_Index - 1
			If _GUICtrlListView_GetItemText($hListView, $i) == $s_File Then Return
		Next
		$i_Size = FileGetSize($s_Path)
		$iSizeAll += $i_Size
		_GUICtrlListView_AddItem($hListView, $s_File)
		_GUICtrlListView_AddSubItem($hListView, $i_Index, _WinAPI_PathRemoveExtension($s_Path), 1)
		_GUICtrlListView_AddSubItem($hListView, $i_Index, _GetSize($i_Size), 2)
		_GUICtrlListView_SetColumn($hListView, 0, 'Имя файла (' & $i_Index + 1 & ')')
		_GUICtrlListView_SetColumn($hListView, 2, 'Всего: ' & _GetSize($iSizeAll))
		_GUICtrlListView_SetItemChecked($hListView, $i_Index)
		GUICtrlSetState($nCheckAll, $GUI_ENABLE)
		GUICtrlSetState($nButtonDelAll, $GUI_ENABLE)
	EndIf
EndFunc   ;==>_DragFile_ListView

Func _GetSize($i_Size)
	Local $sReturnString = ''
	If Number($i_Size) < 0 Then Return $sReturnString
	Switch Number($i_Size)
		Case 0 To 1023
			$sReturnString = StringFormat('%.2f b', $i_Size)
			Return $sReturnString
		Case 1024 To 1048575
			$sReturnString = StringFormat('%.2f kb', $i_Size / 1024)
			Return $sReturnString
		Case 1048576 To 1073741823
			$sReturnString = StringFormat('%.2f Mb', $i_Size / (1024 * 1024))
			Return $sReturnString
		Case Else
			$sReturnString = StringFormat('%.2f Gb', $i_Size / (1024 * 1024 * 1024))
			Return $sReturnString
	EndSwitch
EndFunc   ;==>_GetSize

Func _FileSearch($sPath, $sFileMask = '*', $iFlag = 0, $iSubdir = 1)
	;фильтры для поиска нужно указывать через ;
	;$iFlag = 0 - Файлы и папки (по умолчанию)
	;$iFlag = 1 - Только файлы
	;$iFlag = 2 - Только папки
	;$iSubdir = 1 - Искать во всех подкаталогах (по умолчанию)
	;$iSubdir = 0 - Искать только в самой папке
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $sSubdir, $aMasks
	If StringRight($sPath, 1) == '\' Then
		$sPath = StringTrimRight($sPath, 1)
	EndIf
	If $iSubdir Then
		$sSubdir = ' /S /B'
	Else
		$sSubdir = ' /B'
	EndIf
	Switch $iFlag
		Case 1
			$sAttrib = ' /A-D'
		Case 2
			$sAttrib = ' /AD'
		Case Else
			$sAttrib = ' /A'
	EndSwitch

	$sOut = StringToBinary('0' & @CRLF, 2)
	$aMasks = StringSplit($sFileMask, ';')

	For $i = 1 To $aMasks[0]
		$hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '"' & $sSubdir & $sAttrib, @SystemDir, @SW_HIDE, 6)
		While 1
			$sRead = StdoutRead($hDir, False, True)
			If @error Then
				ExitLoop
			EndIf
			If $sRead <> "" Then
				$sOut &= $sRead
			EndIf
		WEnd
	Next
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Then
		Return SetError(1)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch

Func _Get_Folder()
	Local $s_Message = 'Выберите папку в которой будем искать файлы.'
	GUICtrlSetData($nInputPath, '')
	WinSetOnTop($hGui, '', 0)
	Local $sNewFolder = FileSelectFolder($s_Message, '', 6)

	If @error Or Not $sNewFolder Or (Not _WinAPI_PathIsDirectory($sNewFolder)) Then
		WinSetOnTop($hGui, '', 1)
		GUICtrlSetData($nInputPath, 'Нужно выбрать папку.')
		GUICtrlSetTip($nInputPath, 'Перетащите сюда папку или кликните по кнопке справа.')
		GUICtrlSetState($nButtonSearch, $GUI_DISABLE)
		Return
	EndIf
	GUICtrlSetData($nInputPath, $sNewFolder)
	GUICtrlSetTip($nInputPath, $sNewFolder)
	GUICtrlSetState($nButtonSearch, $GUI_ENABLE)
	WinSetOnTop($hGui, '', 1)
	Return
EndFunc   ;==>_Get_Folder

WinAPIEx.au3

Что делает:
1. Можно перетащить файлы с нужным расширением в ListView.
2. Можно перетащить папку, в которой будем искать нужные файлы в Input.
3. Можно выбрать папку, нажав кнопку "...".
4. После выбора папки, нажать кнопку "Найти". Искать будет и в поддиректориях.

В ListView:
1-ая колонка - имя файла;
2-ая - полный путь к папке поиска + имя файла без расширения (чтобы потом создать папку для обработки файла).
3-ья - размер файла.

При поиске в папке проверки на одинаковые имена файлов нет. Я не знаю, нужна она или нет.
При перетаскивании файлов проверка на одинаковые имена происходит.
Одну и ту же папку, не удалив все строки, второй раз в обработку не возьмет.

Чтобы сделать обработку файлов , мне нужны все утилиты, *.dll к ним и файлы для обработки.

Расширение для поиска и перетаскивания файлов *.au3 (для теста).
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
madmasles [?]
Что делает:1. Можно перетащить файлы с нужным расширением в ListView.2. Можно перетащить папку, в которой будем искать нужные файлы в Input.
я так понял что это еще нужно реализовать? при тесте скрипта возможности перетягивания я не увидел
 

joiner

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

madmasles [?]
1. Можно перетащить файлы с нужным расширением в ListView.2. Можно перетащить папку, в которой будем искать нужные файлы в Input.
ОС ХР SP3.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Александр
Писал в XP SP3 32, сейчас проверил на 7-32, все работает.
 

joiner

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

Код:
WARNING: $WS_EX_ACCEPTFILES: possibly used before declaration.
$hGui = GUICreate($sTitle, 600, 335, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES,
WARNING: $WS_EX_TOPMOST: possibly used before declaration.
$hGui = GUICreate($sTitle, 600, 335, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST)
: WARNING: $WS_EX_CLIENTEDGE: possibly used before declaration.
        18, $ES_READONLY, BitOR($WS_EX_CLIENTEDGE,
: WARNING: $WS_EX_STATICEDGE: possibly used before declaration.
        18, $ES_READONLY, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE)
 ERROR: $WS_EX_ACCEPTFILES: undeclared global variable.
$hGui = GUICreate($sTitle, 600, 335, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES,
 1 error(s), 4 warning(s)
добавил стили в глобальные переменные , ошибка исчезла, но результат как было описано выше..
версия AutoIT 3.3.6.1
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Александр
Судя по Вашему результату, у Вас или не последняя версия WinAPIEx.au3, или не все файлы из комплекта (их три: WinAPIEx.au3, APIConstants.au3 и APIErrors.au3)
Те константы, на которые у Вас вылезает ошибка, находятся в WindowsConstants.au3, а он включен в APIConstants.au3.
 

joiner

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

Tosyk

Новичок
Сообщения
206
Репутация
0
madmasles сказал(а):
Tosyk
Получилась у меня следующая заготовка

оого, как чудесно всё работает! :D

madmasles сказал(а):
Tosyk
Чтобы сделать обработку файлов , мне нужны все утилиты, *.dll к ним и файлы для обработки.
кинул ссылку в пм
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Tosyk
madmasles [?]
При поиске в папке проверки на одинаковые имена файлов нет. Я не знаю, нужна она или нет.
Так она нужна или нет? И, если нужна, то какая (имена, размер, MD5)? И что делать, если файлы одинаковые?
Tosyk [?]
цель моя: научится на примере написанию подобных скриптов,
Если что-то непонятно, то Вы спрашивайте.
 
Автор
Tosyk

Tosyk

Новичок
Сообщения
206
Репутация
0
madmasles сказал(а):
Tosyk
madmasles [?]
При поиске в папке проверки на одинаковые имена файлов нет. Я не знаю, нужна она или нет.
Так она нужна или нет? И, если нужна, то какая (имена, размер, MD5)? И что делать, если файлы одинаковые?
думаю проверка не нужна, так как файлы будут "распаковываться" каждый в свою папку (с именем исходного файла), по адресу где они расположены

madmasles сказал(а):
Tosyk [?]
цель моя: научится на примере написанию подобных скриптов,
Если что-то непонятно, то Вы спрашивайте.
конечно, думаю вопросов возникнет достаточно :smile:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Tosyk
Мне непонятно, что делать с промежуточными файлами *.dae. Удалять или как?
 
Автор
Tosyk

Tosyk

Новичок
Сообщения
206
Репутация
0
Помогите пожалуйста завершить скрипт. :beer:

уж очень он нужен
 
Верх