Ru-Board.club
← Вернуться в раздел «Программы»

» AutoIT

Автор: KiLL
Дата сообщения: 20.06.2010 01:30
Может кому-то будет интересен один из кирпичиков полной автоматизации развертывания системы из образа. Знаюи что тема давно раскрыта, однако методы/способы/требования у меня свои, следовательно и инструменты тоже. Решения этого вопроса не нашел, поэтому набросал сам. В процессе написания использовал DeviceAPI.au3. Проверено на двух системах.


Цитата:
#include "DeviceAPI.au3"

;Смысл программы в том, чтобы закрывая окна Мастера Нового Оборудования,
; она считала количество таких закрытых окон и сравнивала это кол-во
; с текущим количеством неизвестных устройств, а когда кол-во последних
; будет равно количеству закрытых окон (система установит все что может
; установить), мы запустим установку неизвестных устройств.
;
;Можно конечно из окна Мастера нового оборудования из WindowText брать
; наименование конкретного неизвестного устройства, затем находить его в
; текущем массиве и выбивать из "обоймы", но это уже лишнее, хотя и точнее.

$wcount = 0

;Перебирая окна, закрываем паразитные и ведем статистику
Do
$var = WinList()
For $i = 1 to $var[0][0]
If $var[$i][0] <> "" AND BitAnd( WinGetState($var[$i][1]), 2 ) Then
Select
Case $var[$i][0] = "Изменение параметров системы"
WinClose("Изменение параметров системы")
Case $var[$i][0] = "Мастер нового оборудования"
WinClose("Мастер нового оборудования")
$wcount+=1
EndSelect
EndIf
Next
Until $wcount=GetCurrentUnknownDevicesCount()

;Если все сходится, то завершаем работу
MsgBox(64,"","Неизвестных устройств: " & $wcount)

;=======================================================================
; Функция подсчета неизвестных устройств в данный момент
;=======================================================================
Func GetCurrentUnknownDevicesCount()

$i=0

;Строим список классов устройств
_DeviceAPI_GetAllDevices()

;Просматривая устройства, считаем количество устройств с пустымы класом и идентификатором
While _DeviceAPI_EnumDevices()
$classname = _DeviceAPI_GetClassName(_DeviceAPI_GetDeviceRegistryProperty($SPDRP_CLASSGUID))
$classGUID = _DeviceAPI_GetDeviceRegistryProperty($SPDRP_CLASSGUID)
If $classname="" AND $classGUID="" Then $i+=1
WEnd

;Очищаем за собой
_DeviceAPI_DestroyDeviceInfoList()

Return $i

EndFunc
Автор: Orion_76
Дата сообщения: 20.06.2010 13:05
Вот вроде нашел что надо,
ТОлько не пойму, что она возвращает..


Код: Func _GetFileSecurityDACL($sFile)
If Not IsDeclared("DACL_SECURITY_INFORMATION") Then
Const $DACL_SECURITY_INFORMATION = 0x4
Local $return
Local $hAdvapi32 =
DllOpen("advapi32.dll")
If Not FileExists($sFile) Then Return SetError(1,0,0)
$return =
DllCall($hAdvapi32,"long","GetFileSecurity", _
"str",$sFile, _
"dword", $DACL_SECURITY_INFORMATION, _
"ptr",0, _
"dword",0, _
"dword*",0)
If Not $return[5] Then Return SetError(1,0,0)
Local $strucSD =
DllStructCreate("byte[" & $return[5] & "]")
$return =
DllCall($hAdvapi32,"long","GetFileSecurity", _
"str",$sFile, _
"dword", $DACL_SECURITY_INFORMATION, _
"ptr",
DllStructGetPtr($strucSD), _
"dword",
DllStructGetSize($strucSD), _
"dword*",0)
If Not $return[0] Then Return SetError(1,0,0)
DllClose($hAdvapi32)
Return
DllStructGetData($strucSD,1)
EndFunc
Автор: Kar1son
Дата сообщения: 21.06.2010 08:04
Orion_76
так то что написал AZJIO как раз подходит
Автор: Orion_76
Дата сообщения: 21.06.2010 10:33
Kar1son

Код:
Func _cacls()
$accfncombo0 = GUICtrlRead($accfncombo)
$access00 = GUICtrlRead($access)
Switch $access00
Case $access00 = "запрет"
$access0 = "N"
Case $access00 = "чтение"
$access0 = "R"
Case $access00 = "запись"
$access0 = "W"
Case $access00 = "изменение"
$access0 = "C"
Case $access00 = "полный"
$access0 = "F"
Case Else
$access0 = "F"
EndSwitch
ShellExecute(@SystemDir & '\cacls.exe', '"' & $sTarget & '" /t /e /p "' & $accfncombo0 & '":' & $access0, '', '', @SW_HIDE)
EndFunc ;==>_cacls
Автор: Kar1son
Дата сообщения: 21.06.2010 11:14

Цитата:
Func _cacls()
$accfncombo0 = GUICtrlRead($accfncombo)
$access00 = GUICtrlRead($access)
Switch $access00
Case $access00 = "запрет"
$access0 = "N"
Case $access00 = "чтение"
$access0 = "R"
Case $access00 = "запись"
$access0 = "W"
Case $access00 = "изменение"
$access0 = "C"
Case $access00 = "полный"
$access0 = "F"
Case Else
$access0 = "F"
EndSwitch
ShellExecute(@SystemDir & '\cacls.exe', '"' & $sTarget & '" /t /e /p "' & $accfncombo0 & '":' & $access0, '', '', @SW_HIDE)
if $access0 = "C" then
return True
else
return False
endif

EndFunc ;==>_cacls


а голова на что? принцип полностью показан, тут три строки дописать
Автор: Orion_76
Дата сообщения: 21.06.2010 11:45
Kar1son


Цитата:
а голова на что? принцип полностью показан, тут три строки дописать


Прочтите внимательней код..

$access0 - читается из ГУЯ
Эта функция для УСТАНОВКИ разрешений
А надо для ПРОВЕРКИ

т.е что-то типа:

$res=ФункцияПроверкиРазрешений($ИмяФайла,$ИмяПользователя)
If $res==1 Then
...
else
...
EnfIF

В принципе вроде нужную функцию нашел(в посте выше-Func _GetFileSecurityDACL($sFile)
)
Она возвращает какой-то секъюрити дескриптор (в WinApi не силен), т.е. шестнадцатиричную строку.
Осталось только догадаться, как из него нужную инфу выдернуть.



Автор: Kar1son
Дата сообщения: 21.06.2010 12:01
Orion_76 ладно убедил слепой дятел это все таки я
Автор: AZJIO
Дата сообщения: 21.06.2010 13:20
Решил занятся [more=переводом]1. Для частичной автоматизации сделал замену строк по всем файлам справки:

Цитата:
<p><b>Return Value</b></p> на <p><b>Возвращаемое значение</b></p>
<td width="10%" valign="top">Success:</td> на <td width="10%" valign="top">Успешно:</td>
<td valign="top">Failure:</td> на <td valign="top">Неудачно:</td>
<p><b>Remarks</b></p> на <p><b>Примечание</b></p>
<p><b>Related</b></p> на <p><b>Связана с функцией</b></p>
<p><b>Example</b></p> на <p><b>Пример</b></p>
value="Text:Open this Script"> на value="Text:Открыть">
<h1>Function Reference</h1> на <h1>Функция</h1>
<p><b>Parameters</b></p> на <p><b>Параметры</b></p>
<b>[optional]</b> на <b>[опционально]</b>
<p><b>See Also</b></p> на <p><b>Также смотреть</b></p>
Search <a href=" на Найти <a href="
</a> in MSDN Library на </a> в библиотеке MSDN
<td>set @error</td> на <td>установить @error</td>

</b></p>
None.<br>
на
</b></p>
нет.<br>


Перевожу функции _WinAPI_*****
Пока перевёл 8 функций

Цитата:
_WinAPI_Beep.htm
_WinAPI_CreateFile.htm
_WinAPI_EnableWindow.htm
_WinAPI_GetFileSizeEx.htm
_WinAPI_GetFocus.htm
_WinAPI_GetMousePos.htm
_WinAPI_GetMousePosX.htm
_WinAPI_GetMousePosY.htm


Для компиляции использую htm2chm

[/more] справки UDF - UDFs3.chm
Автор: vicbox777
Дата сообщения: 21.06.2010 13:29
Orion_76 11:45 21-06-2010
Цитата:
Она возвращает какой-то секъюрити дескриптор (в WinApi не силен), т.е. шестнадцатиричную строку.
Осталось только догадаться, как из него нужную инфу выдернуть.


Код: Func _CheckSecurityDescriptor($Descriptor)
Local $strucSD =
DllStructCreate("byte[" & (StringLen($Descriptor)/2)-1 & "]")
DllStructSetData($strucSD,1,$Descriptor)
Local $hAdvapi32 =
DllOpen("advapi32.dll")
Local $return =
DllCall($hAdvapi32,"int","IsValidSecurityDescriptor", _
"ptr",
DllStructGetPtr($strucSD))
DllClose($hAdvapi32)
If $return[0] = 0 Then Return SetError(1,0,0)
Return 1
EndFunc
Автор: Orion_76
Дата сообщения: 21.06.2010 16:09
vicbox777

Цитата:
IsValidSecurityDescriptor

Вроде просто определяет валидность структуры дескриптора?
Автор: vicbox777
Дата сообщения: 21.06.2010 16:51

Цитата:
Вроде просто определяет валидность структуры дескриптора?

Извиняюсь.
Автор: Orion_76
Дата сообщения: 21.06.2010 23:56
vicbox777
Бывает-))

Блин...весь инет перерыл...
Неужели это не актуально....?
Есть примеры на С и на VB...
но там кода строк на 150...
Можно конечно вывод cacls распарсить...или WMI
Но это ненадежно или через Ж...
Автор: Cegpuk
Дата сообщения: 22.06.2010 01:39
Как этот же скрипт можно написать лучше (в самом прямом смысле)?

Код: HotKeySet("{numpaddot}", "Terminate")
HotKeySet("{numpad1}", "LeftToggle")
HotKeySet("{numpad3}", "RightToggle")

Global $StartLeft
Global $StartRight

While 1=1
    While $StartLeft = True
        Left()
    WEnd
    While $StartRight = True
        Right()
    WEnd
    Sleep(10)
WEnd

Func Right()
    Send("{left down}")
    Sleep(150)
    Send("{left up}")
    Send("{right down}")
    Sleep(600)
    Send("{right up}")
    Send("{up down}")
    Sleep(50)
    Send("{up up}")
    Sleep(50)
EndFunc

Func Left()
    Send("{right down}")
    Sleep(150)
    Send("{right up}")
    Send("{left down}")
    Sleep(600)
    Send("{left up}")
    Send("{up down}")
    Sleep(50)
    Send("{up up}")
    Sleep(50)
EndFunc

Func LeftToggle()
    $StartLeft = NOT $StartLeft
EndFunc

Func RightToggle()
    $StartRight = Not $StartRight
EndFunc

Func Terminate()
Exit 0
EndFunc
Автор: degid
Дата сообщения: 22.06.2010 16:58

Цитата:
Kar1son


Цитата: а голова на что? принцип полностью показан, тут три строки дописать


Прочтите внимательней код..

$access0 - читается из ГУЯ
Эта функция для УСТАНОВКИ разрешений
А надо для ПРОВЕРКИ
Автор: ringer
Дата сообщения: 22.06.2010 19:22
сделал скрипт(ехе) задача которого нажимать кнопки в окне приложения, и выбирать в списке(по типу списка диспетчера задач) указанные строки, сохранять инфу из окна в файл
что делать при запуск определяется параметрами запуска

сам запуск этого скрипта(ехе) производится через веб-панель т.е. через PHP exec
на локальной системе, где и апач и приложение запущены от одного юзера все работает без проблем

на системе где апач запущен от SYSTEM, а приложение от моего юзера, этот скрипт(ехе) запускается, но не выдает инфы видимо из-за того что он запускается от имени SYSTEM и просто не видит окно приложения

сделал еще один скрипт(ехе), который запускает первый от того же юзера, от которого запущено приложение
судя по диспетчеру задач он действительно стал запускаться от того же юзера что и приложение, но взять инфу из окна, или нажать кнопку так и не смог

п.с. сделал тоже самое, только вместо своего скрипта подставил calc.exe
в диспетчере задач calc.exe появился от моего имени, но самого окна на рабочем столе не появилось, может в этом проблема
хотя в моем скрипте(ехе) нет гуи
Автор: AZJIO
Дата сообщения: 22.06.2010 22:50
degid
а почему XCACLS? Я попробовал cacls, который уже есть в системе, с ним тоже выдаёт инфу, вот тест:

Цитата:
cacls C:\WINDOWS
PAUSE
с консоли прочитать и отдетектить регулярным выражением вроде не проблема.


ringer
А можно пример, хотя бы того же диспетчера задач, чтоб пытался нажать на нём кнопки, я бы у себя проверил.
А почему не видно ожидание активного окна? Ведь скрипт явно не успеет его открыть, как все клики уже отработают...
Автор: ringer
Дата сообщения: 22.06.2010 23:02
пробовал запускать скрипт вручную - т.е. даблклик по ехе шнику
проблем с не успеванием не было
Автор: Orion_76
Дата сообщения: 23.06.2010 00:31
AZJIO
Оно все понятно-))
можно и через cacls.exe, можно и через WMI(что мне кажется проще и надежнее)...
Но...как гриться...хоть совершенству нет предела... но хочется через WinApi..-)))
Вообще..ИМХО...должна БЫ быть udf-функция-)) с подобным функционалом...

В принципе основная задумка такая:
Есть отличный фриварный файл-менеджер FreeCommander
В нем можно настроить менюшки или хоткеии на запуск прог с передачей параметров (типа- путь к текущей папке, путь к выделенному файлу и т.д.)
т.е. нам больше ничего и не надо.. передал скрипту(Autoit) имя нужного файла-папки... и делай с ним че хочешь (если права у тебя есть-))
Вот сдесь и начинается самое интересно...
Скрипт делает (hardlink,жесткая ссылка и т.д.)Символьную ссылку на выделенную папку или файл в нужном каталоге. Но функция , делающая этот линк возвращает только ПОЛУЧИЛОСЬ или НЕПОЛУЧИЛОСЬ, а почему не получилось -(( Х\З...
толи к исходному файлу-папке доступ запрещен(занят, или прав нет) ,толи в конечную папку запись запрещена (занята. прав нет)...
Автор: AZJIO
Дата сообщения: 23.06.2010 09:22
ringer
Так поставь мессагу, типа если найдено окно то выдать "Доступно", если не найдено, то "Недоступно", и далее заняться соответствующей проблемой. Заголовок и текст в окне обязательно с использованием Au3Info.exe, иногда там могуть быть символ &-амперсанд, который скрыт на кнопке, но из-за этого она не видна.


Цитата:
If WinExists($title) Then
MsgBox(0, '+++++', 'Доступно '&$title)
Else
MsgBox(0, '--------', 'Не доступно '&$title)
EndIf
Автор: ringer
Дата сообщения: 23.06.2010 15:33
проблема именно из-за запуска приложения и скрипта от разных юзеров
решил разбив на два скрипта
апач дергает скрипт1, скрипт1 сохранят параметр запуска в файл
скрипт2 висит процессах(запущен тем же пользователем что и приложение), и ждет когда появится процесс скрипта1
как появился он читает файл и отрабатывает в зависимости от команды указанной в файле

update
поспешил я, видимо проблема вообще в другом крылась
пока я слежу за скриптом через удаленный рабочий стол - все работает
но как только выключаю удаленку, сркипт перестает работать

т.е. если я не залоген, винда не рисует гуи, и окна просто нет
полагаю можно не пробовать запустить и скрипт и приложение от system т.к. там точно никакого гуи нет
Автор: AZJIO
Дата сообщения: 23.06.2010 19:36
Интересует способы смены языка и формат языкового файла программы...

1. Формат, где номер строки является номером переменной.
Цитата:
Сохранить всё
Вырезать
Копировать
Вставить
Недостаток - нет смысловых названий переменных в теле скрипта.

2. Формат записи в виде ini, возможно здесь не обязательно читается как ini, а например создание переменной до знака "=" со значением после знака равно, т.е. построчно разделение в массив и далее разделение строки знаком "=" для генерации переменных.
Цитата:
strYesToAll=Да для всех
strNoToAll=Нет для всех
strYes=Да
strNo=Нет
strIgnore=Пропустить
strAbort=Прервать
strCancel=Отмена
strOk=ОК
Плюсы такого формата - обработка в цикле и имена переменных имеют смысловое значение.

3. Привязка к цифре.
Цитата:
2=Включена
8=Выключить
5=Включить
Такой метод попробовал, но опять же не смысловые имена переменных.

4. Пример с элементом и всплавыющей подсказкой
Цитата:
btErase=|Ластик|Стереть часть рисунка
btFlood=|Заливка|Залить область


5. Чтение с разделителем TAB
Цитата:
List1                &Список
ListUp                &Вверх
ListDown            &Вниз


6. Смешанный формат.

Некоторые переменные можно просто изменить, а для интерфейса нужно ещё использовать GUICtrlSetData. Получается, что лучший вариант - 2.
Автор: AZJIO
Дата сообщения: 26.06.2010 01:27
Название: Русский справочник по Win 32 API
Автор: Тарас Сорока
(chm)

Название: Справочник по Win32 API
Автор: Мерзляков Николай
(одним файлом exe)

страничка
или
wasm.ru
_________________
Регулярные выражения (на русском)
shtogrin.com
shop.piter.com
Html-версия (Дж.Фридл.) с сайта издательства, 375K ба, редакция 1.01, страничка
wiki.linuxformat.ru
Автор: Pleshner
Дата сообщения: 27.06.2010 20:25
Ребята, у кого есть: можете кинуть несколько примеров работы через сабж с Firefox? Как я понял, сАмо просто работать через готовую либу FF.au3.

Кто-нить может кинуть в меня примерами работы - просто рабочие скрипты чего угодно через FF.au3, нужно очень быстро написать свой скрипт, и что-то с ходу никак не могу въехать что да как там... Спасибо!
Автор: AZJIO
Дата сообщения: 28.06.2010 03:19
Pleshner
На офсайте работает поиск, но для этого нужно зарегистрироваться.
Вобщем прописать её #include <FF.au3>, а функции есть с переводом на русский
Вот тема. И обязательно проверить совместимость версий AutoIt3 и FF.au3, последняя 0.6 работает с v3.3.0.0.
Автор: Dmitri_Andreev
Дата сообщения: 30.06.2010 14:37
Друзья помогите пожалуйста.

Имеется строка
GUICtrlCreateLabel ("Строка с текстом", 20, 30, 0x0000)
длинна которой увеличивается по мере ее заполнения, можно ли, в процессе выполнения скрипта, получить размер этой строки в пикселях?
Автор: ViSiToR
Дата сообщения: 30.06.2010 14:56
Dmitri_Andreev 15:37 30-06-2010
Цитата:
можно ли, в процессе выполнения скрипта, получить размер этой строки в пикселях?

Можно. В шапке есть ссылка на библиотеку «_GUICtrlCreateTFLabel» (в разделе GUI), а в ней есть функция получения длины строки.
Автор: djuuj
Дата сообщения: 30.06.2010 20:50
Здравствуйте. Вот такая проблемка, мне нужно отправиться на сайт, кликнуть на картинку, вследствие чего откроется НОВОЕ ОКНО браузера, и продолжать работу уже в новом окне. Вот до нового окна всё понятно, а вот как получить доступ к новому окну не имею представления.. Кто знает, подскажите пожалуйста.
Искал ответ добросовестно, был почти уверен, что это распространённая и уже давно решённая проблема, но пока только нашёл точно такие же вопросы без ответов, или ответы с попытками обойтись старым окном..
Автор: KiLL
Дата сообщения: 30.06.2010 22:47
djuuj
_IEAttach поможет если вы знаете заголовок окна, урл, текст в теле документа, дескриптор и т.п. В случае с текстовыми элементами совпадение требуется не полное. А еще функция может подключиться к конкретной инстанции открытого браузера по номеру. Вы наверное плохо искали.
Автор: Dmitri_Andreev
Дата сообщения: 01.07.2010 15:12
ViSiToR Спасибо... разобрался.
Автор: AZJIO
Дата сообщения: 03.07.2010 04:19
Утилита - [more=Поиск дубликатов]
Код: ; @AZJIO 2010.07.09
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_OutFile=Search_duplicates.exe
#AutoIt3Wrapper_icon=Search_duplicates.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseAnsi=y
#AutoIt3Wrapper_Res_Comment=-
#AutoIt3Wrapper_Res_Description=Search_duplicates.exe
#AutoIt3Wrapper_Res_Fileversion=0.1.0.0
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=n
#AutoIt3Wrapper_Res_LegalCopyright=AZJIO
#AutoIt3Wrapper_Res_Language=1049
#AutoIt3Wrapper_Run_AU3Check=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <Crypt.au3>
#include <File.au3>
#include <Array.au3>

#include <GUIConstantsEx.au3>
;#include <GuiListView.au3>
Global $Debug_LV = False
#include <ListViewConstants.au3>
#NoTrayIcon
Global $Stack[50], $Stack1[50]
Global $aArr, $a, $MD5Path, $Dubl
HotKeySet('{ESC}', "_Quit") ; выход по ESC

;создание оболочки

$Gui = GUICreate("Поиск дубликатов файлов", 500, 444, -1, -1, 0x00040000, 0x00000010) ; размер окна
$CatchDrop = GUICtrlCreateInput("", 0, 0, 500, 440)
GUICtrlSetState(-1, 136)
GUICtrlSetResizing(-1, 1)
$StatusBar = GUICtrlCreateLabel(@CRLF&'Строка состояния', 5, 380, 480, 30)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 2)

$restart = GUICtrlCreateButton("R", 480, 2, 18, 20)
GUICtrlSetTip(-1, "Перезапуск утилиты")
GUICtrlSetResizing(-1, 512 + 256 + 32 + 4)

$About = GUICtrlCreateButton("?", 460, 2, 18, 20)
GUICtrlSetTip(-1, "О программе")
GUICtrlSetResizing(-1, 512 + 256 + 32 + 4)

GUICtrlCreateLabel("используйте drag-and-drop", 170, 5, 160, 18)
GUICtrlSetResizing(-1, 32 + 256 + 512)

GUICtrlCreateLabel("Папки", 15, 10, 60, 17)
GUICtrlSetResizing(-1, 3 + 32 + 256 + 512)
$folder = GUICtrlCreateList("", 10, 25, 480, 100)
GUICtrlSetResizing(-1, 7 + 32 + 512)

GUICtrlCreateLabel("Дубликаты", 15, 132, 60, 18)
GUICtrlSetResizing(-1, 3 + 32 + 256 + 512)

_Dubl()

$context = GUICtrlCreateContextMenu($Dubl)
$contextOpen = GUICtrlCreateMenuitem ("Открыть",$context)


; $Select = GUICtrlCreateButton("Выбор", 180, 355, 70, 25)
; GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$Clear = GUICtrlCreateButton("Очистить", 260, 355, 70, 25)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$Search = GUICtrlCreateButton("Поиск", 340, 355, 70, 25)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)
$Delete = GUICtrlCreateButton("Удалить", 420, 355, 70, 25)
GUICtrlSetResizing(-1, 512 + 256 + 64 + 4)

$aSizePath=''
$folderList = ''
$aArrOut=''

GUISetState()
_Crypt_Startup()

While 1
    $msg = GUIGetMsg()
    Select
        ; drag-and-drop - принятие каталогов
        Case $msg = -13
            $triger = 0
            If @GUI_DropId = $CatchDrop Then
                $aFolder = StringSplit(GUICtrlRead($CatchDrop), '|')
                $GuiPos = WinGetPos($Gui)
                GUICtrlSetPos($CatchDrop, $GuiPos[2], 0)
                GUICtrlSetData($CatchDrop, '')
                GUICtrlSetPos($CatchDrop, 0, 0)
                For $i = 1 To $aFolder[0]
                    If StringInStr(FileGetAttrib($aFolder[$i]), "D") = 0 Then
                        $triger = 1
                    Else
                        GUICtrlSetData($folder, StringRegExpReplace($aFolder[$i], '(?:.*)\\(.*)$', '\1'))
                        $folderList &= '|' & $aFolder[$i]
                    EndIf
                Next
            EndIf
            If $triger = 1 Then
                $triger = 0
                MsgBox(0, "Мелкая ошибка", 'Перетаскивайте каталоги, а не файлы.')
            EndIf

        Case $msg = $About
            _About()

            ; Очистка (обнуляем все весомые переменные)
        Case $msg = $Clear
            GUICtrlDelete ($Dubl)
            _Dubl()
            $folderList = ''
            GUICtrlSetData($folder, '')
            $aSizePath = ''
            $aArr = ''
            $aArrT = ''
            $TempMD5 = ''
            $aArrOut = ''
            $aArrMD5 = ''
            GUICtrlSetData($StatusBar,@CRLF&'Строка состояния')

            ; Открыть
        Case $msg = $contextOpen or $msg = $Dubl
            ShellExecute(StringTrimRight(GUICtrlRead(GUICtrlRead ($Dubl)),1))

            ; Удаление
        Case $msg = $Delete
            If $folderList='' or $aArrOut='' Then ContinueLoop
            GUICtrlSetData($StatusBar, 'Удаление выполняется...')
            For $i = 1 to $aArrOut[0][0]
                If GUICtrlRead($aArrOut[$i][0],1)=1 And FileExists($aArrOut[$i][1]) Then

                    FileDelete($aArrOut[$i][1])
                    GUICtrlDelete($aArrOut[$i][0])
                    $aArrOut[$i][0]=''
                    $aArrOut[$i][1]=''
                EndIf
            Next
            _GUICtrlListView_SetColumnWidth($Dubl, 0, $LVSCW_AUTOSIZE)
            If _GUICtrlListView_GetColumnWidth($Dubl, 0)<480 Then _GUICtrlListView_SetColumnWidth($Dubl, 0, 480)
            GUICtrlSetData($StatusBar, 'Удаление завершено!')

            ; Поиск
        Case $msg = $Search
            If $folderList='' Then ContinueLoop
            If $aSizePath<>'' Then ; перед повторным поиском делаем очистку
                GUICtrlDelete ($Dubl)
                _Dubl()
                Sleep(50)
                $aSizePath = ''
                $aArr = ''
                $aArrT = ''
                $TempMD5 = ''
                $aArrOut = ''
                $aArrMD5 = ''
            EndIf

GUICtrlSetData($StatusBar, 'Создание списка файлов...')
            $aSizePath = ''
            $timer = TimerInit()
            If StringLeft($folderList, 1)='|' Then $folderList = StringTrimLeft($folderList, 1)
            $aFolderList = StringSplit($folderList, '|')
            For $i = 1 To $aFolderList[0] ; выполняем поиск в цикле для каждого добавленного пути
                If FileExists($aFolderList[$i]) Then
                    FileFindNextFirst($aFolderList[$i])
                    While 1
                        $tempname = FileFindNext()
                        If $tempname = "" Then ExitLoop
                        $aSizePath &= '|' & FileGetSize($tempname) & '|' & $tempname
                    WEnd
                EndIf
            Next
            $aArrT = StringSplit(StringTrimLeft($aSizePath, 1), "|") ;создаём одномерный массив, имитацию двумерного массива.
            $aSizePath='1' ;очистка и индикатор выполненого поиска
;_ArrayDisplay($aArrT, "$aArrT") ; одномерный массив всех файлов (размер | путь)
;_ArrayDisplay($aArrT,"$aArrT",-1,-1,-1,-1, 'размер|путь') ; одномерный массив всех файлов (размер | путь)
            Dim $aArr[$aArrT[0] / 2 + 1][2]
            $aArr[0][0] = $aArrT[0] / 2
            For $i = 1 To $aArrT[0]
                If Mod($i, 2) = 0 Then
                    $aArr[$i / 2][0] = Int($aArrT[$i - 1])
                    $aArr[$i / 2][1] = $aArrT[$i]
                EndIf
            Next
            ; (массив | сортировка по возврастанию | начальный индекс сортировки | конечный | колонка сортировки)
            _ArraySort($aArr, 0, 1, $aArr[0][0], 0)
;_ArrayDisplay($aArr, "$aArr") ; сортированный двумерный массив всех файлов (размер | путь)

            $aArrOut = ''
            Dim $aArrOut[1][2]
            $a = 0
            $0b = 0
            $gp=0
            
            $kol=0
            $triger = 0
            $triger2 = 0
            $TempSize = ''
            For $i = 1 To $aArr[0][0] ; формирование временного массива файлов c совпадающими размерами, но вместа размера указан MD5
            $kol+=1
                If $aArr[$i][0] = $TempSize Then
                    If $triger = 0 Then
                        $MD5Path = ''
                        $MD5Path &= '|' & _Crypt_HashFile($aArr[$i - 1][1], 0x00008003) & '|' & $aArr[$i - 1][1]
                    EndIf
                    $triger = 1
                    $MD5Path &= '|' & _Crypt_HashFile($aArr[$i][1], 0x00008003) & '|' & $aArr[$i][1]
                Else
                    $triger = 0
                EndIf
; переключение тригера для срабатывания обработки MD5 если совпадение существвали на последних элементах, чтоб правильно завершить цикл
                If $aArr[0][0]=2 and $triger = 1 Then $triger2 = 1 ; исключение для всего двух одинаковых файлов
                If $i = $aArr[0][0] Then $triger = 0
                If $triger = 0 And $triger2 = 1 Then ; обработка временного массива с совпавшими размерами файлов ======================================


                    $aMD5PathT = StringSplit(StringTrimLeft($MD5Path, 1), "|") ;создаём одномерный массив, имитацию двумерного массива.
;_ArrayDisplay($aMD5PathT, "$aMD5PathT") ; сортированный массив всех файлов (размер | путь)

; конвертируем одномерный массив в двумерный.
                    Dim $aArrMD5[$aMD5PathT[0] / 2 + 1][2]
                    $aArrMD5[0][0] = $aMD5PathT[0] / 2
                    For $o = 1 To $aMD5PathT[0]
                        If Mod($o, 2) = 0 Then
                            $aArrMD5[$o / 2][0] = $aMD5PathT[$o - 1]
                            $aArrMD5[$o / 2][1] = $aMD5PathT[$o]
                        EndIf
                    Next

;_ArrayDisplay($aArrMD5, "$aArrMD5- до сортировки") ; временный сортированный массив совпавших по размеру файлов, но с разными MD5 (MD5 | путь)
                    _ArraySort($aArrMD5, 0, 1, $aArrMD5[0][0], 0)
;_ArrayDisplay($aArrMD5, "$aArrMD5- после сортировки") ; временный сортированный массив совпавших по размеру файлов, но с разными MD5 (MD5 | путь)

                    ;===================================================================
                    ; вложенная, подобная копия основного алгоритма, с разницей MD5 вместо размера
                    ; формирование временного массива совпадающих файлов $aArrOut по MD5
                    $0triger = 0
                    $0triger2 = 0
                    $TempMD5 = ''
                    For $0i = 1 To $aArrMD5[0][0]
                        If $a-$0b < 3 Then
                            $a+=100
                            ReDim $aArrOut[$a][2]
                        EndIf
                        If $aArrMD5[$0i][0] = $TempMD5 Then
                            If $0triger = 0 Then
                                $0b += 1
                                $gp+=1
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&', текущий: '&$kol &', группа: '&$gp &', добавлено: '&$0b &', время: '& Ceiling(TimerDiff($timer)/1000)&' сек, размер: '& Ceiling($aArr[$i][0]/1000)& 'кб' &@CRLF& $aArrMD5[$0i - 1][1])
                            GUICtrlCreateListViewItem( '---'&$gp&'---',$Dubl)
                            GUICtrlSetColor(-1,0x777777)
                            GUICtrlSetBkColor ( -1, 0xffffff )

                                $aArrOut[$0b][0] = GUICtrlCreateListViewItem($aArrMD5[$0i - 1][1],$Dubl)
                                GUICtrlSetColor(-1,0xaa0000)

                                $aArrOut[$0b][1] = $aArrMD5[$0i - 1][1]
                            EndIf
                            $0triger = 1
                            $0b += 1
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&', текущий: '&$kol &', группа: '&$gp &', добавлено: '&$0b &', время: '& Ceiling(TimerDiff($timer)/1000) &' сек, размер: '& Ceiling($aArr[$i][0]/1000)& 'кб' &@CRLF& $aArrMD5[$0i][1])
                            $aArrOut[$0b][0] = GUICtrlCreateListViewItem($aArrMD5[$0i][1],$Dubl)
                            GUICtrlSetState(-1,1)
                            $aArrOut[$0b][1] = $aArrMD5[$0i][1]
                        Else
                            $0triger = 0
                        EndIf
                        $TempMD5 = $aArrMD5[$0i][0]

                        ;_GUICtrlListView_SetColumn($Dubl, 0, ' ', 480)
                    Next
                EndIf ;==================================================================================================================
                If $triger = 1 Then
                    $triger2 = 1
                Else
                    $triger2 = 0
                EndIf
                $TempSize = $aArr[$i][0]
                _GUICtrlListView_SetColumnWidth($Dubl, 0, $LVSCW_AUTOSIZE)
            Next
            If _GUICtrlListView_GetColumnWidth($Dubl, 0)<480 Then _GUICtrlListView_SetColumnWidth($Dubl, 0, 480)
                    ReDim $aArrOut[$0b+1][2]
                    $aArrOut[0][0]=$0b
                    If $0b = 0 Then
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&' файлов, дубликатов не найдено!')
                    Else
GUICtrlSetData($StatusBar, 'Всего: ' &$aArr[0][0]&', групп: '&$gp &', добавлено: '&$0b&', отмечено: '&$0b-$gp &', время: '& Ceiling(TimerDiff($timer)/1000)&' сек' &@CRLF& 'Готово!')
                    EndIf
            ;_ArrayDisplay($aArrOut, "$aArrOut")
            ; Перезапуск
        Case $msg = $restart
            _restart()
        Case $msg = -3
            _Crypt_Shutdown()
            Exit
    EndSelect
WEnd

; добавлено из ListViewConstants.au3, для экономии размера скрипта
Func _GUICtrlListView_SetColumnWidth($hWnd, $iCol, $iWidth)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If IsHWnd($hWnd) Then
Return _SendMessage($hWnd, $LVM_SETCOLUMNWIDTH, $iCol, $iWidth)
Else
Return GUICtrlSendMsg($hWnd, $LVM_SETCOLUMNWIDTH, $iCol, $iWidth)
EndIf
EndFunc

Func _GUICtrlListView_GetColumnWidth($hWnd, $iCol)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If IsHWnd($hWnd) Then
Return _SendMessage($hWnd, $LVM_GETCOLUMNWIDTH, $iCol)
Else
Return GUICtrlSendMsg($hWnd, $LVM_GETCOLUMNWIDTH, $iCol, 0)
EndIf
EndFunc

Func _Dubl()
    $GuiPos = WinGetPos($Gui)
    $Dubl = GUICtrlCreateListView(' ', 10, 150, $GuiPos[2]-26, $GuiPos[3]-251, $LVS_NOCOLUMNHEADER +$LVS_SHOWSELALWAYS, $LVS_EX_CHECKBOXES + $LVS_OWNERDRAWFIXED)
    GUICtrlSendMsg($Dubl, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    GUICtrlSendMsg($Dubl, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_TRACKSELECT, $LVS_EX_TRACKSELECT)
    GUICtrlSetBkColor(-1, 0xf0f0f0) ; 0xE0DFE3 - цвет стандартный серый
    GUICtrlSetResizing(-1, 7 + 32 + 64)
EndFunc

;========================================
; функция поиска всех файлов в каталоге (NIKZZZZ)

Func FileFindNextFirst($FindCat)
    $Stack[0] = 1
    $Stack1[1] = $FindCat
    $Stack[$Stack[0]] = FileFindFirstFile($Stack1[$Stack[0]] & "\*.*")
    Return $Stack[$Stack[0]]
EndFunc ;==>FileFindNextFirst

Func FileFindNext()
    While 1
        $file = FileFindNextFile($Stack[$Stack[0]])
        If @error Then
            FileClose($Stack[$Stack[0]])
            If $Stack[0] = 1 Then
                Return ""
            Else
                $Stack[0] -= 1
                ContinueLoop
            EndIf
        Else
            If StringInStr(FileGetAttrib($Stack1[$Stack[0]] & "\" & $file), "D") > 0 Then
                $Stack[0] += 1
                $Stack1[$Stack[0]] = $Stack1[$Stack[0] - 1] & "\" & $file
                $Stack[$Stack[0]] = FileFindFirstFile($Stack1[$Stack[0]] & "\*.*")
                ContinueLoop
            Else
                Return $Stack1[$Stack[0]] & "\" & $file
            EndIf
        EndIf
    WEnd
EndFunc ;==>FileFindNext

Func _restart()
    Local $sAutoIt_File = @TempDir & "\~Au3_ScriptRestart_TempFile.au3"
    Local $sRunLine, $sScript_Content, $hFile

    $sRunLine = @ScriptFullPath
    If Not @Compiled Then $sRunLine = @AutoItExe & ' /AutoIt3ExecuteScript ""' & $sRunLine & '""'
    If $CmdLine[0] > 0 Then $sRunLine &= ' ' & $CmdLineRaw

    $sScript_Content &= '#NoTrayIcon' & @CRLF & _
            'While ProcessExists(' & @AutoItPID & ')' & @CRLF & _
            ' Sleep(10)' & @CRLF & _
            'WEnd' & @CRLF & _
            'Run("' & $sRunLine & '")' & @CRLF & _
            'FileDelete(@ScriptFullPath)' & @CRLF

    $hFile = FileOpen($sAutoIt_File, 2)
    FileWrite($hFile, $sScript_Content)
    FileClose($hFile)

    Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sAutoIt_File & '"', @ScriptDir, @SW_HIDE)
    Sleep(1000)
    Exit
EndFunc ;==>_restart

Func _Quit()
    Exit
EndFunc ;==>_Quit

Func _About()
GUISetState(@SW_HIDE, $Gui)
$font="Arial"
$Gui1 = GUICreate("О программе", 270, 180, -1, -1, -1, 0x00000080)
    GUISetBkColor (0xf8c848)
    GUICtrlCreateLabel('Search duplicates', 0, 20, 270, 23, 0x01)
    GUICtrlSetFont (-1,15, 600, -1, $font)
    GUICtrlSetColor(-1,0xa21a10)
    GUICtrlCreateLabel('поиск дубликатов файлов', 0, 49, 270, 46, 0x01)
    GUICtrlSetFont (-1,13, 600, -1, $font)
    GUISetFont (9, 600, -1, $font)
    GUICtrlSetColor(-1,0xa21a10)
    GUICtrlCreateLabel('Версия 0.1 от 9.07.2010', 55, 100, 210, 17)
    GUICtrlCreateLabel('Сайт:', 55, 115, 40, 17)
    $url=GUICtrlCreateLabel('http://azjio.ucoz.ru', 92, 115, 170, 17)
    GUICtrlSetCursor(-1, 0)
    GUICtrlSetColor(-1, 0x0000ff)
    GUICtrlCreateLabel('WebMoney: R939163939152', 55, 130, 210, 17)
    GUICtrlCreateLabel('Copyright AZJIO © 2010', 55, 145, 210, 17)
    GUISetState(@SW_SHOW, $Gui1)
$msg = $Gui1
    While 1
     $msg = GUIGetMsg()
     Select
        Case $msg = $url
            ShellExecute ('http://azjio.ucoz.ru')
        Case $msg = -3
            $msg = $Gui
            GUIDelete($Gui1)
            GUISetState(@SW_SHOW, $Gui)
            ExitLoop
        EndSelect
WEnd
EndFunc

Страницы: 12345678910111213

Предыдущая тема: Проблемы с VMware Workstation (часть 4)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.