Войти

Показать полную графическую версию : [Архив - Часть 1.3] AutoIt скрипты


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [18] 19 20 21 22 23 24 25 26

mrak1990
27-04-2007, 23:20
Creat0R
Разобрался наконец с твоим скриптом. Но остался один маленький вопросик:
Local $WinListArr[$WinList[0][0]+2]
В скриптах AutoIT нужно при объявлении массива указывать в квадратных скобках число элементов? Если так, то почему ты приписываешь "+2", а не "+1"?

Creat0R
27-04-2007, 23:49
mrak1990
почему ты приписываешь "+2", а не "+1"?
Функция WinList возвращает массив заголовок окон, но в этом массиве нет заголовка для рабочего стола, поэтому при объявлении массива требуется увеличить его на один элемент, в момент обработки массива он остаётся пустым, но в конце функции я задаю этому пустому элементу значение ровняющееся заголовку рабочего стола ($WinListArr[$WinListArr[0]] = "classname=Progman"), чтобы в родительской функции ( UpdateExplorer() ) небыло необходимости в определении заголовка для рабочего стола, он будет браться их возвращённого массива (последний элемент).

mrak1990
27-04-2007, 23:57
Creat0R
Я всё это понял. Просто для чего два дополнительных элемента?

Creat0R
28-04-2007, 01:36
mrak1990
для чего два дополнительных элемента?
Когда объявляем массив, нужно добавлять ещё один элемент, который будет содержать общее число элементов, в данном случае, нужно два (т.е тоже число элемнтов как и у массива возвращённого от WinList, плюс один элемент (WinList[0][0] содержит общее число элементов этого массива)), а дополнительный для того чтобы поместить в него ещё один заголовок окна (рабочего стола)...

Можно конечно и обойтиться +2, вот так:


Func _ExplWinGetList()
Local $WinList = WinList("classname=CabinetWClass")
If IsArray($WinList) Then
Local $WinListArr[UBound($WinList)+1]
For $iW = 1 To $WinList[0][0]
$WinListArr[$iW] = $WinList[$iW][0]
Next
$WinListArr[0] = $WinList[0][0]+1
$WinListArr[$WinListArr[0]] = "classname=Progman"
Return $WinListArr
Else
Return ""
EndIf
EndFunc


В этом случае Ubound($WinList) ровняется WinList[0][0]+1 (нуливой элемент содержащий общее количество элементов, и все остальные элементы), поэтому мы добавляем только +1.

amel27
28-04-2007, 11:42
TERMINALА возможно чтобы обновления записывальсь в текстовый файл?
где изменения сделать?подправил скрипт для случая файла и исправил один недочет в скрипте...

З.Ы. имхо скрипт не очень практичен, но не если есть интерес принимаются любые предложения по доработке... заодно можно придать более внятный вид - по аналогии с энумераторами RegEnum* с индексом... типа HotFixEnum

Diamond
28-04-2007, 14:25
Защита от повторного запуска
P.S. Просьба, не тестировать этот скрипт из редактора.
$objService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
$colProc=$objService.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '%" & @ScriptName & "%'")
If $colProc.Count > 1 Then
Msgbox(0+48,"Совпадений: " & $colProc.Count,"Скрипт уже запущен")
Exit(1)
EndIf
;~ --== Здесь должен быть код Вашего скрипта ==--
Отслеживание вновь запущенных процессов:$strComputer = "."
$objWMIService = ObjGet("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$colMonitoredProcesses=$objWMIService.ExecNotificationQuery("select * from __instancecreationevent " & _
" within 1 where TargetInstance isa 'Win32_Process'")
While 1
$objLatestProcess = $colMonitoredProcesses.NextEvent
MsgBox(0,"Обнаружен запуск",$objLatestProcess.TargetInstance.Name)
WEndОтслеживание завершающихся процессов:
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$colMonitoredProcesses = $objWMIService.ExecNotificationQuery("select * from __instancedeletionevent " _
& "within 1 where TargetInstance isa 'Win32_Process'")
While 1
$objLatestProcess = $colMonitoredProcesses.NextEvent
MsgBox(0,"Обнаружено завершение",$objLatestProcess.TargetInstance.Name)
WEndОтследить запуск определённого процесса:
$process='notepad.exe'
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$objEvents = $objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = '" & $process & "'")
MsgBox(0,"","Ожидание событий ...")
While 1
$objReceivedEvent = $objEvents.NextEvent
MsgBox(0,"",$process & " запущен")
WEndОтследить завершение определённого процесса:
$process='notepad.exe'
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$objEvents = $objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = '" & $process & "'")
MsgBox(0,"","Ожидание событий ...")
While 1
$objReceivedEvent = $objEvents.NextEvent
MsgBox(0,"",$process & " завершён")
WEndА этот скрипт я как-то писал для отслеживания вируса по его PID (долгая история...)
С его помощью можно определить, какие программы запускали на компьютере в ваше отсутствие,
остаётся только перенаправить информацию в текстовой файл...#Include <date.au3>
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$colMonitoredProcesses = $objWMIService.ExecNotificationQuery("select * from __instancedeletionevent " _
& "within 1 where TargetInstance isa 'Win32_Process'")
While 1
$objLatestProcess = $colMonitoredProcesses.NextEvent
$pdel = _Now()
MsgBox(0,"", "Имя: " & $objLatestProcess.TargetInstance.Name & @CRLF & _
"Расположение: " & $objLatestProcess.TargetInstance.ExecutablePath & @CRLF & _
"Командная строка: " & $objLatestProcess.TargetInstance.CommandLine & @CRLF & _
"PID: " & $objLatestProcess.TargetInstance.ProcessId & @CRLF & _
"Приоритет: " & $objLatestProcess.TargetInstance.Priority & @CRLF & _
"Время запуска: " & WMIDateStringToDate($objLatestProcess.TargetInstance.CreationDate) & @CRLF & _
"Время завершения: " & $pdel & @CRLF & _
"____________________________________")
WEnd

;###########################################
Func WMIDateStringToDate($str)
Local $WMIDateStringToDate
If not $str = "" Then
$WMIDateStringToDate=StringMid($str,7,2) & '.' & StringMid($str,5,2) & '.' & _
StringLeft($str,4) & chr(32) & StringMid($str,9,2) & ':' & _
StringMid($str,11,2) & ':' & StringMid($str,13,2)
EndIf
Return $WMIDateStringToDate
EndFuncЗ.Ы.
Не мешало бы скрыть присутствие скрипта в списке процессов.
Слышал, что это можно сделать через WinApi, но я не знаю как...

Creat0R
28-04-2007, 15:34
Diamond
Хорошие функции!

Правда с первой что-то не получается :(
При первом запуске выдаёт два совпадения и что скрипт уже запущен, хотя это не так.

P.S
Это только если имя скрипта test.au3, в других случаях вроде всё нормально.

Кстати, а можно ли как то получить список скрытых процессов?

mrak1990
28-04-2007, 17:33
Creat0R
Я тут переписал твой скрипт в таком виде, в каком, как мне кажется проще его понять начинающим. Плюс добавил комментарии. Вот что из этого получилось.
#cs
;~ Toogle Hidden folders and files program - This is AutoIt source code (AutoIt vesrion 3.2.2.0).
;~ Author: G.Sandler a.k.a CreatoR - http://creator-lab.ucoz.ru
;~ ICQ: 5607655
#ce

#NoTrayIcon

$RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
If RegRead($RegKey, "Hidden") = 1 Then
RegWrite($RegKey, "Hidden", "REG_DWORD", 2)
Else
RegWrite($RegKey, "Hidden", "REG_DWORD", 1)
EndIf

UpdateExplorer()

Func UpdateExplorer()
Local $OldOpt = Opt("WinTitleMatchMode", 4) ;Устанавливаем параметр AutoIT, отвечающий за идендификацию окон
Local $WinExpListArr = _ExplWinGetList() ;Получаем массив, возвратённый функцией "_ExplWinGetList"
Local $Hwnd
If IsArray($WinExpListArr) Then
For $iWin = 1 To $WinExpListArr[0]
$Hwnd = WinGetHandle($WinExpListArr[$iWin])
DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0) ;Посылаем команду на обновление всех папок и Рабочего стола
Next
EndIf
Opt("WinTitleMatchMode", $OldOpt) ;Устанавливаем старое значение параметра AutoIT, отвечающего за идендификацию окон
EndFunc

Func _ExplWinGetList()
Local $WinList = WinList("classname=CabinetWClass") ;Получаем массив, содержащий список открытых папок и их HWND
If IsArray($WinList) Then
Local $WinListArr[UBound($WinList)+1] ;Создаём новый массив, который будет содержать ТОЛЬКО ИМЕНА папок, CLASSNAME Рабочего стола и кол-во элементов в массиве
$WinListArr[0] = $WinList[0][0]+1 ;Присваеваем нулевому элементу массива число, содержащее кол-во элементов в массиве
$WinListArr[$WinListArr[0]-1] = "classname=Progman" ;Присваиваем последнему элементу массива "Classname" Рабочего стола
For $iW = 1 To $WinListArr[0]-2 ;Вычесть двойку нужно из-за того, что первый и последний элемент массива не содержат имен папок
$WinListArr[$iW] = $WinList[$iW][0] ;Присваиваем первому и всем последующим элементам массива названия открытых окон
Next
Return $WinListArr ;Возвращаем массив, содержащий список всех окон, "Classname" Рабочего стола и кол-во элементов в массиве
Else
Return ""
EndIf
EndFunc

Creat0R
28-04-2007, 20:33
mrak1990
Я тут переписал твой скрипт в таком виде, в каком, как мне кажется проще его понять начинающим. Плюс добавил комментарии.
Спасибо.

Правда комментарии немного не точные, так будет правильнее (также немного изменил функции, раньше если небыло найдено окон, то рабочий стол тоже не обновлялся, а также во второй функции сразу помещаются в массив уникальные идентификаторы (hWnd), чтобы не нужно было их определять в первой функции - они ведь возвращаются от WinList() ):


Func _UpdateExplorer()
;Устанавливаем параметр, отвечающий за метод распознвания заголовок окон (4 - самый чувствительный),
;и помещаем в переменную $OldOpt исходное значение этого параетра.
Local $OldOpt = Opt("WinTitleMatchMode", 4)
;Получаем массив содержащий заголовки окон проводника Windows вкдючая Рабочего стола (по средствам функции _ExplWinGetList).
Local $WinExpListArr = _ExplWinGetList()
;Если возвратился массив (а значит найдены заголовки окон),
;то перебираем весь массив, с целью обновления каждого окна (по его заголовку из элементов массива).
If IsArray($WinExpListArr) Then
For $iWin = 1 To $WinExpListArr[0]
;Вызов функции для обновления текущего окна
;(по уникальному идентификатору который содержится в текущем элементе массива).
DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr[$iWin], "int", 0x111, "int", 28931, "int", 0)
Next
Else
;Если не вернулся массив (значит небыли найдены окна проводника), тогда обновляем только Рабочий стол
;(переменная $WinExpListArr теперь содержит только один уникальный идентификатор Рабочего стола).
DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr, "int", 0x111, "int", 28931, "int", 0)
EndIf
;Устанавливаем исходное значение (заданное значение при входе в функцию) параметра,
;отвечающего за метод распознвания заголовок окон.
Opt("WinTitleMatchMode", $OldOpt)
EndFunc

Func _ExplWinGetList()
;Получаем массив, содержащий список существующих заголовок окон проводника Windows (Explorer),
;и их уникальный идентификатор (hWnd).
Local $WinList = WinList("classname=CabinetWClass")
;Если вернулся массив (а значит найдено одно или более окон), тогда делаем перебор по массиву,
;в целях отсеивания только уникальных идентификаторов существующих окон (проводника Windows).
If IsArray($WinList) Then
;Объявляем массив, который будет собдержать список уникальных идентификаторов существующих окон.
Local $WinListArr[UBound($WinList)+1]
;Перебираем полученный массив $WinList, и отсеиваем в новый массив $WinListArr
;только уникальные идентификаторы окон Explorer.
For $iW = 1 To $WinList[0][0]
$WinListArr[$iW] = $WinList[$iW][1]
Next
;Присваеваем нулевому элементу нового массива ($WinListArr), значение ровняющееся общему количеству элементов в этом массиве.
$WinListArr[0] = UBound($WinListArr)-1
;Присваиваем последнему элементу этого же массива, уникальный идентификатор (основываясь на "Classname") Рабочего стола.
$WinListArr[$WinListArr[0]] = WinGetHandle("classname=Progman")
;Возвращаем массив, содержащий список идентификаторов всех существующих окон проводника (вкючая Рабочего стола).
Return $WinListArr
Else
;Если функция WinList() не "вернула" массив (а значит небыло найдено окон проводника),
;тогда возвращаем только один уникальный идентификатор Рабочего стола.
Return WinGetHandle("classname=Progman")
EndIf
EndFunc

amel27
29-04-2007, 09:08
DiamondНе мешало бы скрыть присутствие скрипта в списке процессов.
Слышал, что это можно сделать через WinApi, но я не знаю как...вот вариант на основе скрипта с оффсайта, к сожалению он полезен только в учебных целях...
с другой стороны, все остальные способы будут оффтопом для этой ветки. ;)$process = "script.exe"

While 1
WinWait ("Диспетчер задач Windows")
$index = ControlListView ("Диспетчер задач Windows", "", 1009, "FindItem", $process)
If $index = -1 Then
Sleep(5)
Else
$hwnd = ControlGetHandle ("Диспетчер задач Windows", "", 1009)
DllCall("user32.dll", "int", "SendMessage", "hwnd", $hwnd, "int", 0x1008, "int", $index, "int", 0)
EndIf
Wend

Diamond
29-04-2007, 11:39
Creat0R
При первом запуске выдаёт два совпадения и что скрипт уже запущен, хотя это не так.У меня всё нормально, хотя если запускать его из редактора то обнаруживается лишнее "совпадение".
Кстати, а можно ли как то получить список скрытых процессов?Думаю, что процесс будет скрыт только от "Диспетчера задач Windows" и подобных ему, т.е. от WMI он не скроется.

amel27
к сожалению он полезен только в учебных целях...Действительно к сожалению...
Наверное что-то вроде этого я и искал, но не ожидал что это будет работать именно так...
В любом случае, Спасибо!
все остальные способы будут оффтопом для этой ветки.Любой способ который можно использовать в AutoIT, или который имеет прямое отношение к скрипту AutoIT, разве это оффтоп? Хотя...

Скажем, я хочу знать какие программы запускали на моём компьютере в моё отсутствие.
Проблема в том, что более опытный юзер может легко обнаружить и завершить мой "шпионский" процесс.
У меня возникла идея не скрывать, а просто сделать невозможным его завершение, т.е. скомпилировать скрипт и назвать его к примеру lsass.exe.
Хотя и примитивно - зато надёжно. ;)

Diamond
29-04-2007, 13:40
Creat0R
Я понял почему обнаруживается совпадение. Если открыть скрипт в редакторе (даже незапускать) то командная строка редактора будет содержать путь к скрипту, а это уже одно "совпадение".
Попробуй закрыть редактор и запустить скрипт снова. ;)

Creat0R
29-04-2007, 15:25
Diamond
если запускать его из редактора то обнаруживается лишнее "совпадение"
Я запускал сам скрипт, редактор вовсе не открывал (с браузера сразу скрипт пишется на рабочий стол ;) - кстати если интересно, могу выложить тут небольшой код). Но как я упоминул, скрипт именуется как test.au3, при другом имени всё вроде ок, даже и не знаю почему так (может у меня уже запущен подобный скрипт, и он не виден в диспетчере задач :idontnow: ).

[hr]

Есть у меня один вопрос - как можно проверить определённое окно, на наличие ControlID, но способ нужен надёжный, я написиал вот такую функцию (см. далее), но она не везде срабатывает, к примеру в браузере Opera, возвращаются не все ControlID, хотя в Au3Info.exe нужные (мне, для проверки) ControlID видны:


Func _ControlIDIsExists($hWnd, $ControlID)
If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd)
If Not WinExists($hWnd) Then Return SetError(1, 0, 0)
Local $ClassesArr = StringSplit(WinGetClassList($hWnd), @LF)
If IsArray($ClassesArr) Then
For $i = 1 To UBound($ClassesArr)-1
If $ClassesArr[$i] = $ControlID Then Return True
Next
EndIf
Return False
EndFunc

amel27
29-04-2007, 18:06
DiamondСкажем, я хочу знать какие программы запускали на моём компьютере в моё отсутствие.
Проблема в том, что более опытный юзер может легко обнаружить и завершить мой "шпионский" процесс.
У меня возникла идея не скрывать, а просто сделать невозможным его завершение, т.е. скомпилировать скрипт и назвать его к примеру lsass.exe.угу, типичное поведение трояна... Проблема в том, что "мимикрия", хуки и прочие фокусы могут конфликтовать с настройками безопасности системы, а также перехватываться антивирусами и файерволами. На самом деле задача регистрации запускаемых файлов решается штатными средствами администрирования, без привлечения программ-шпионов и прочих ухищрений - прежде всего это средства аудита файловой системы, кроме того можно оформить подписку на любые системные WMI-события... никаких "левых" процессов при этом не создается, т.к. все выполняется средствами системы. Именно это я и имел ввиду говоря про оффтоп...

Creat0RЕсть у меня один вопрос - как можно проверить определённое окно, на наличие ControlIDControlGetHandle() не устраивает? Кстати, почему именно ControlID?.. а если скажем ClassName?

Creat0R
29-04-2007, 22:18
amel27
ControlGetHandle() не устраивает?
Я не уверен что понял... ControlGetHandle() вернёт hWnd, а мне нужно проверить наличие Control.

почему именно ControlID?.. а если скажем ClassName?
Мне не важно, мне нужно проверить существование Control...
Дело в том, что в разных версиях определённой программы (в этом случае браузер Opera), меняются постоянно(?) ClassNameNN/ControlID, вот мне нужно как то проверить, существует ли в текущей версии определённый Control, если нет, то я буду перебирать их последовательность (обычно меняется только цифра).
К примеру вот такой класс - "OperaWindowClass14" - нужно проверить, есть ли он в программе (в окне), не смистился ли.

amel27
30-04-2007, 04:52
Creat0R
Я не уверен что понял... ControlGetHandle() вернёт hWnd, а мне нужно проверить наличие Control.…ну, в смысле если контрола нет, то и не вернет hwid... Зачем тянуть весь список, если нужно проверить только один?

Мне не важно, мне нужно проверить существование Control...есть такой фокус, когда для поиска контролов используется функция поиска окон... так как контрол по сути то же окно, только дочернее. К сожалению штатный "AutoIt Window Info" не показывает информацию о "хозяине" для дочерних окон, я использовал HwndSpy... жаль он шароварный. :( ; Поиск Control по его классу (аналогично можно сделать и по заголовку)
; штатными средствами и через API, на примере CsiTE4

$WinClass = "SciTEWindow" ; Класс головного окна
$CtrlClass1 = "SciTEWindowContent" ; Класс дочернего окна 1-го уровня
$CtrlClass2 = "Scintilla" ; Класс дочернего окна 2-го уровня

; Поиск средствами API
$hAPI0 = DLLCall ("user32.dll", "hwnd", "FindWindow", _
"str", $WinClass, _
"int", 0 )
$hAPI1 = DllCall ("user32.dll", "hwnd", "FindWindowEx", _
"hwnd", $hAPI0 [0], _
"int", 0 , _
"str", $CtrlClass1, _
"int", 0 )
$hAPI2 = DllCall ("user32.dll", "hwnd", "FindWindowEx", _
"hwnd", $hAPI1 [0], _
"int", 0 , _
"str", $CtrlClass2, _
"int", 0 )

; Поиск штатными средствами AutoIT через поиск контрола
$BakWTM = Opt ("WinTitleMatchMode", 4) ; Включаем поиск по классам
$hCtrl = ControlGetHandle("classname=" & $WinClass, '', 350)

; Поиск штатными средствами AutoIT через поиск окна
$BakWSC = Opt ("WinSearchChildren", 1) ; Включаем поиск по вложенным окнам
$hWind = WinGetHandle ("classname=" & $CtrlClass2)

; Вывод результата:
MsgBox (0, 'Test', 'WinAPI:' & @TAB & 'ClassName' & @TAB & $hAPI2 [0] & @CRLF & _
'AutoIT:' & @TAB & 'ControlID ' & @TAB & $hCtrl & @CRLF & _
'AutoIT:' & @TAB & 'ClassName' & @TAB & $hWind & @CRLF )
; Возвращаем настройки
Opt ("WinTitleMatchMode", $BakWTM)
Opt ("WinSearchChildren", $BakWSC)

Creat0R
30-04-2007, 06:28
amel27
…ну, в смысле если контрола нет, то и не вернет hwid... Зачем тянуть весь список, если нужно проверить только один?
Хм, а я как то не подумал в эту сторону (видимо нужно раньше ложиться спать :biggrin: ), спасибо!

есть такой фокус, когда для поиска контролов используется функция поиска окон... так как контрол по сути то же окно, только дочернее.
Вот за эту инфу тоже спасибо, не знал что контроли могут распознваться используя функции поиска окон, и также не знал (из самой функции) что можно подбирать ControlID через classname=....

я использовал HwndSpy... жаль он шароварный.
Есть WinSpy... бесплатный вроде, но не уверен что он отдаёт нужную инфу.

Спасибо ещё раз большое за пример/инфу, буду пробовать это использовать :) .

Diamond
30-04-2007, 07:48
Creat0R
Процесс в котором обнаруживается совпадение, скорее всего виден в Диспетчере задач.
Попробуй индифицировать его по параметрам командной строки:
$CommandString='Test.au3'

;~ Соединяемся с WMI
$objService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
;~ Задаём параметры объекта
$colProc = $objService.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '%" & $CommandString & "%'")
;~ Цикл по элементам объекта-коллекции
For $Proc In $colProc
Msgbox(0+48,"Обнаружен процесс: " & $Proc.name,"Командная строка запуска:" & @CR & $Proc.CommandLine)
Next

amel27
30-04-2007, 17:44
Creat0R

Краткий (промежуточный) отчет о самопальных _FileSelectFolder и подобных функций… На время их активности действительно прерывается любая работа AutoIT-скрипта, причем отключаются все механизмы диспетчеризации вызовов, включая AdLib и GUIRegisterMsg. Впрочем, это вполне логично, так как управление полностью передается системной функции. Отсюда становится понятно, почему разработчики не внесли функциональность HWID в свои функции выбора… просто они не стали заморачиваться разработкой своих функций, а взяли те же системные API-функции (aka wrapper).

Особенность _FileSelectFolder (и аналогичных) в том, что ее поведение управляется набором специальных сообщений SendMessage, которые:
- функция может инициализировать себе сама через вызов специальной (CallBack) функции,
- окно выбора может получить извне.

Первый случай не реализуем средствами AutoIT по причине отсутствия поддержки указателей на функцию. Это ограничение можно обойти подключением внешних DLL, содержащих требуемые функции и способных возвращать их указатели. Одна из таких реализаций предложена на форуме оффсайта, к сожалению, она не подходит для нашего случая по указанным ранее причинам, так как опирается на механизм GUIRegisterMsg… Поэтому потребуется писать свою специфическую DLL, либо расширить функциональность предложенной – в любом случае это придется делать на чем-то другом, отличном от AutoIT - способном компилировать DLL, дружить с GUI и обязательно фриварном.

Второй случай в принципе можно реализовать на AutoIT, но потребуется дополнительный скрипт, управляющий поведением основного на время выполнения системных функций выбора… при этом придется решить ряд вопросов по синхронизации этих процессов. Кроме того, этот вариант очень ограничен по функциональности, так как управляющий скрипт не будет получать информации о состоянии окна главного скрипта (оперативные сообщения). Например, можно попытаться задать начальную папку или текст статусной строки, но управлять кнопкой «Ok» или реагировать на ошибки ввода не получится.

mrak1990
30-04-2007, 19:59
Creat0R
Взял на себя смелость собрать дистрибутив этой проги (выглядит он точно так же), чтобы ты его у себя на сайте обновил. В коде ничего не мнеял. Только опечатки убрал:
#cs
;~ Toogle Hidden folders and files program - This is AutoIt source code (AutoIt vesrion 3.2.2.0).
;~ Author: G.Sandler a.k.a CreatoR - http://creator-lab.ucoz.ru
;~ ICQ: 5607655
#ce

#NoTrayIcon

$RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
If RegRead($RegKey, "Hidden") = 1 Then
RegWrite($RegKey, "Hidden", "REG_DWORD", 2)
Else
RegWrite($RegKey, "Hidden", "REG_DWORD", 1)
EndIf

UpdateExplorer()

Func _UpdateExplorer()
;Устанавливаем параметр, отвечающий за метод распознавания заголовок окон (4 - самый чувствительный),
;и помещаем в переменную $OldOpt исходное значение этого параметра.
Local $OldOpt = Opt("WinTitleMatchMode", 4)
;Получаем массив, содержащий заголовки окон проводника Windows (включая Рабочего стола), по средствам функции _ExplWinGetList.
Local $WinExpListArr = _ExplWinGetList()
;Если возвратился массив (а значит найдены заголовки окон),
;то перебираем весь массив, с целью обновления каждого окна (по его hWnd из элементов массива).
If IsArray($WinExpListArr) Then
For $iWin = 1 To $WinExpListArr[0]
;Вызов функции для обновления текущего окна
;(по уникальному идентификатору, который содержится в текущем элементе массива).
DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr[$iWin], "int", 0x111, "int", 28931, "int", 0)
Next
Else
;Если не вернулся массив (значит не были найдены окна проводника), тогда обновляем только Рабочий стол
;(переменная $WinExpListArr теперь содержит только один уникальный идентификатор Рабочего стола).
DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr, "int", 0x111, "int", 28931, "int", 0)
EndIf
;Устанавливаем исходное значение (заданное значение при входе в функцию) параметра,
;отвечающего за метод распознавания заголовок окон.
Opt("WinTitleMatchMode", $OldOpt)
EndFunc

Func _ExplWinGetList()
;Получаем массив, содержащий список существующих заголовок окон проводника Windows (Explorer),
;и их уникальный идентификатор (hWnd).
Local $WinList = WinList("classname=CabinetWClass")
;Если вернулся массив (а значит найдено одно или более окон), тогда делаем перебор по массиву,
;в целях отсеивания только уникальных идентификаторов существующих окон (проводника Windows).
If IsArray($WinList) Then
;Объявляем массив, который будет содержать список уникальных идентификаторов существующих окон.
Local $WinListArr[UBound($WinList)+1]
;Перебираем полученный массив $WinList, и отсеиваем в новый массив $WinListArr
;только уникальные идентификаторы окон Explorer.
For $iW = 1 To $WinList[0][0]
$WinListArr[$iW] = $WinList[$iW][1]
Next
;Присваиваем нулевому элементу нового массива ($WinListArr), значение ровняющееся общему количеству элементов в этом массиве.
$WinListArr[0] = UBound($WinListArr)-1
;Присваиваем последнему элементу этого же массива, уникальный идентификатор (основываясь на "Classname") Рабочего стола.
$WinListArr[$WinListArr[0]] = WinGetHandle("classname=Progman")
;Возвращаем массив, содержащий список идентификаторов всех существующих окон проводника (включая Рабочего стола) и
;общее кол-во элементов в этом массиве
Return $WinListArr
Else
;Если функция WinList() не "вернула" массив (а значит не было найдено окон проводника),
;тогда возвращаем только один уникальный идентификатор Рабочего стола.
Return WinGetHandle("classname=Progman")
EndIf
EndFunc

Вот ссылка: http://ifolder.ru/1856047

P.S. Единственное, что я не смог изменить, это информацию о файле (вкладка "Версия"). Одна программа при изменении коверкает, другая не хочет сохранять.




© OSzone.net 2001-2012