[Архив - Часть 1.3] AutoIt скрипты

Ответить
 • Просмотры: 7
Аватара пользователя
mrak1990

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение mrak1990 »

Creat0R

Я всё это понял. Просто для чего два дополнительных элемента?
Аватара пользователя
Creat0R

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение Creat0R »

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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение amel27 »

TERMINAL
Цитата:



А возможно чтобы обновления записывальсь в текстовый файл?

где изменения сделать?



подправил скрипт для случая файла и исправил один недочет в скрипте...



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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение Diamond »

Защита от повторного запуска

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 
$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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение Creat0R »

Diamond

Хорошие функции!



Правда с первой что-то не получается Изображение

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



P.S

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



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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение mrak1990 »

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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение Creat0R »

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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение amel27 »

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

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение Diamond »

Creat0R

Я понял почему обнаруживается совпадение. Если открыть скрипт в редакторе (даже незапускать) то командная строка редактора будет содержать путь к скрипту, а это уже одно "совпадение".

Попробуй закрыть редактор и запустить скрипт снова. Изображение
Аватара пользователя
Creat0R

Re: [Архив - Часть 1.3] AutoIt скрипты

Сообщение Creat0R »

Diamond


Цитата:



если запускать его из редактора то обнаруживается лишнее "совпадение"



Я запускал сам скрипт, редактор вовсе не открывал (с браузера сразу скрипт пишется на рабочий стол Изображение - кстати если интересно, могу выложить тут небольшой код). Но как я упоминул, скрипт именуется как test.au3, при другом имени всё вроде ок, даже и не знаю почему так (может у меня уже запущен подобный скрипт, и он не виден в диспетчере задач Изображение ).







Есть у меня один вопрос - как можно проверить определённое окно, на наличие 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
Ответить

Вернуться в «AutoIt»