Показать полную графическую версию : [решено] Сокращение / оптимизация скрипта проверки состояния и запуска служб MU
saavaage
26-08-2010, 05:13
Суть: есть скрипт определения состояния служб, ответственных за запуск MU. Кроме того, скрипт позволяет сделать оптимизацию служб, если их конфигурация не позволяет работать MU. Предусмотрен также откат на старые настройки (сделал обновление и снова вернул службы в исходное положение)
Проблема:
1. почему-то не отрабатывает "откат" по службе "Автоматическое обновление". - решено
2. скрипт получился слишком громоздким. Имхо, мне кажется, что его можно значительно сократить (м.б. за счет использование массивов?). Это прежде всего касается следующих блоков скрипта:
а) Func _ServicesStat()
б) Func _SaveOld()
Как мне кажется, эти бесконечные case и If -> Endif - не совсем грамотный путь.
saavaage
27-08-2010, 13:47
проблему удалось решить только так:
1. заменил код:
Func _SaveOld()
GUICtrlSetState($Button_Save, $GUI_DISABLE)
$Save_Event = $sLog3_2
$Save_BITS = $sLog2_2
$Save_MU = $sLog1_2
sleep(1000)
GUICtrlSetState($Button_Save, $GUI_ENABLE)
EndFunc
на:
Func _SaveOld()
GUICtrlSetState($Button_Save, $GUI_DISABLE)
Select
Case $sLog1_2 = '2'
$Save_MU = 'auto'
Case $sLog1_2 = '3'
$Save_MU = 'demand'
Case $sLog1_2 = '4'
$Save_MU = 'disabled'
Case $sLog1_2 = '0'
$Save_MU = 'boot'
Case Else
$Save_MU = 'system'
EndSelect
Select
Case $sLog2_2 = '2'
$Save_BITS = 'auto'
Case $sLog2_2 = '3'
$Save_BITS = 'demand'
Case $sLog2_2 = '4'
$Save_BITS = 'disabled'
Case $sLog2_2 = '0'
$Save_BITS = 'boot'
Case Else
$Save_BITS = 'system'
EndSelect
Select
Case $sLog3_2 = '2'
$Save_Event = 'auto'
Case $sLog3_2 = '3'
$Save_Event = 'demand'
Case $sLog3_2 = '4'
$Save_Event = 'disabled'
Case $sLog3_2 = '0'
$Save_Event = 'boot'
Case Else
$Save_Event = 'system'
EndSelect
sleep(1000)
GUICtrlSetState($Button_Save, $GUI_ENABLE)
EndFunc
2. заменил код:
Func _RestoreOld()
GUICtrlSetState($Button_Restore, $GUI_DISABLE)
RunWait(RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog', 'Start', 'REG_DWORD', $Save_Event))
RunWait(RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\muauserv', 'Start', 'REG_DWORD', $Save_MU))
RunWait(RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BITS', 'Start', 'REG_DWORD', $Save_BITS))
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_Restore, $GUI_ENABLE)
EndFunc
на:
Func _RestoreOld()
GUICtrlSetState($Button_Restore, $GUI_DISABLE)
RunWait('sc config eventlog start= ' & $Save_Event &'', '', @SW_HIDE)
RunWait('sc config wuauserv start= ' & $Save_MU &'', '', @SW_HIDE)
RunWait('sc config BITS start= ' & $Save_BITS &'', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_Restore, $GUI_ENABLE)
EndFunc
Может кто-нибудь все-таки поможет в плане как мне кажется, скрипт можно сократить (смущает большое количество однотипных операций). »
Может кто-нибудь все-таки поможет »
- не указана версия AutoIT, на котором проводится отладка;
- туманное и нечеткое описание задач скрипта;
- скрипт "сходу" нерабочий (ошибки отсутствия .AU3, переменных и т.п.);
- отсутствуют комментарии/структурирование кода
...Вы всё еще чему-то удивляетесь?
saavaage
30-08-2010, 17:39
amel27 & ALL, извините, исправляюсь:
1. версия autoit 3.3.6.1
2. задачи скрипта:
1. индикация состояния служб, необходимых для работы MU (зеленые иконки - соответсвуют, красные -нет)
2. по нажатию на кнопки совершить следующие действия:
- кнопка"Сохранить" - сохранение текущей конфигурации "типа запуска" служб (т.е. конфигурация, которая у юзера поумолчанию)
- кнопка "Старт" - изменение (если необходимо) умолчальных конфигураций служб на конфигурации, которые позволяют MU работать (включая не только изменение типа запуска, но и сам старт служб)
- кнопка "Откат" - если необходимо, позволяют юзеру откатить "новые" настройки (тип запуска) на те, которые у него раньше были (важно, если работаешь на чужом ПК или сам не хочешь держать автообновление и проч. в автозагрузке).
3. скрипт рабочий, но необходимо качать архив mu_services.7z, т.к. без иконок, Вы не увидите его работу. Код был выложен для общей информации и без иконок он работать не будет. кроме того, каюсь, забыл вложить Icons.au3.
4. комментарии добавил,архив перезалил (см. шапку).
Заранее спасибо
скрипт получился слишком громоздким »
поверьте, четыре страницы это не много, тут важно не переусердствовать: излишнее сокращение кода (обычно делается через параметризацию) неизбежно ухудшает читабельность и гибкость, т.е. увеличивает затраты на его восприятие и последующие изменения... уменьшить количество текста на файл можно разделением скрипта на несколько файлов (по функциям) и загрузкой их через INCLUDE... Теперь по-существу дела - что бы я попытался изменить в скрипте:
1. сохранял бы состояние служб не в переменных, а в файле или реестре;
2. избавился от внешней утилиты SC, варианты - реестр, WMI, API;
3. вместо конструкции Select/Case активней использовал массивы (параметризация);
4. только нужные ф-ции из Icons.AU3 перенес в основной код скрипта
5. подключил иконки как ресурс EXE-файла
что Вы думаете по этому поводу?
saavaage
31-08-2010, 12:15
amel27, мда.... не все понял, но:
1. вопрос в том, что я хочу сделать утилиту, которая бы не следила на машшине, т.е. , по возможности, никаких доп. изменений
2. sc - вынужденная необходимость. ввел, когда не получилось изменить через RegWrite тип запуска Автоматического обновления. Плюс -утилита присутствует как в xp, так и в win7
3. массивы пока только планирую начать изучать (я так понял, что нужно смотреть все функции с _Array) Если не затруднит, то можно дать направление, что делать мне в данном случае или, даже, пример
4. если можно, то почему так будет лучше? Меньше весить будет или еще что-то? Просто, этот скрипт- часть утилиты, которую я пытаюсь сделать (там 6 вкладок и уже много инклюдов) и для меня этот вопрос очень важен..
5. не совсем понял? это через file instal или как?
1. дело вкуса, можно и в TEMP... но если скрипт зависнет, все сохранения пропадут
2. насколько помню, Вы его использовали неправильно, но запустить службу через реестр всё равно не выйдет, проще всего через WMI (http://forum.oszone.net/post-899451-893.html)
3. нет, без всяких библиотек,
Select
Case $sLog1_2 = '2'
$Save_MU = 'auto'
Case $sLog1_2 = '3'
$Save_MU = 'demand'
Case $sLog1_2 = '4'
$Save_MU = 'disabled'
Case $sLog1_2 = '0'
$Save_MU = 'boot'
Case Else
$Save_MU = 'system'
EndSelect
Select
Case $sLog2_2 = '2'
$Save_BITS = 'auto'
Case $sLog2_2 = '3'
$Save_BITS = 'demand'
Case $sLog2_2 = '4'
$Save_BITS = 'disabled'
Case $sLog2_2 = '0'
$Save_BITS = 'boot'
Case Else
$Save_BITS = 'system'
EndSelect
Select
Case $sLog3_2 = '2'
$Save_Event = 'auto'
Case $sLog3_2 = '3'
$Save_Event = 'demand'
Case $sLog3_2 = '4'
$Save_Event = 'disabled'
Case $sLog3_2 = '0'
$Save_Event = 'boot'
Case Else
$Save_Event = 'system'
EndSelect
эквивалентен такому:
Dim $aSvcState[5]=['boot','','auto','demand','disabled']
$Save_MU = $aSvcState[$sLog1_2]
$Save_BITS = $aSvcState[$sLog2_2]
$Save_Event= $aSvcState[$sLog3_2]
4. если ф-ций используется мало и они простые, можно их перенести в свой код, но придется разобраться в их работе, плюсы - лучшее понимание своего скрипта, а значит больший над ним контроль (в чужих библиотеках нередки ошибки или нестыковки с версиями AutoIT)
5. AutoIt Wrapper GUI - Расширенная компиляция скриптов (http://autoit-script.ru/index.php/topic,22.0.html)
saavaage
31-08-2010, 13:27
amel27,
по п.2 - там была проблема с переключением "типа запуска" Автообновления, а не сам запуск. Т.е. не отрабатывал такой вариант:
$Save_MU = $sLog1_2
RunWait(RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\muauserv', 'Start', 'REG_DWORD', $Save_MU))
по п.3 -спасибо, супер! Можно немного "разжевать" суть процесса. Я понимаю так:
1. создается массив из 5 элементов (boot, system, auto, demand, disabled)
Dim $aSvcState[5]=['boot','system','auto','demand','disabled']
2. идет присвоение переменным:
$Save_MU - присваивается значение элемента массива $aSvcState[$sLog1_2], причем, насколько я понял [$sLog1_2] -это порядковый номар элемента? Т.е. если $sLog1_2 = 2, то выбирается 2 номер, т.е. auto... и так далее
Правильно?
не отрабатывал такой вариант »RunWait не нужен для запуска штатной ф-ции AutoIT:RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\muauserv', 'Start', 'REG_DWORD', $sLog1_2)
Правильно? »угу, именно так и используются массивы
saavaage
31-08-2010, 15:54
amel27, на эту же тему - попробывал также переделать код с иконками (пришлось делать многомерный массив, т.к. разные условия):
IF $sLog1_1 = 4 Then
$pic1_1 = 'ok.ico'
_ImageGet()
ELSE
$pic1_1 = 'error.ico'
_ImageGet()
EndIf
IF $sLog3_1 = 4 Then
$pic3_1 = 'ok.ico'
_ImageGet()
ELSE
$pic3_1 = 'error.ico'
_ImageGet()
EndIf
IF $sLog1_2 = 2 Then
$pic1_2 = 'ok.ico'
_ImageGet()
ELSE
$pic1_2 = 'error.ico'
_ImageGet()
EndIf
IF $sLog2_2 = 4 Then
$pic2_2 = 'error.ico'
_ImageGet()
ELSE
$pic2_2 = 'ok.ico'
_ImageGet()
EndIf[/CODE]
на:
Dim $aState1[3][4]=[['error.ico','','','ok.ico'], ['','ok.ico','error.ico','error.ico'], ['','ok.ico','ok.ico','error.ico']]
$pic1_1 = $aState1[1][$sLog1_1]
$pic3_1 = $aState1[1][$sLog3_1]
$pic1_2 = $aState1[2][$sLog1_2]
$pic2_2 = $aState1[3][$sLog2_2]
$pic3_2 = $aState1[2][$sLog3_2]
_ImageGet()
и выдало ошибку
C:\Documents and Settings\?????????????\??????? ????\Hotfixes2-1.au3 (145) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$pic1_1 = $aState1[1][$sLog1_1]
$pic1_1 = ^ ERROR
выдало ошибку »
- в команде Dim указывается КОЛИЧЕСТВО элементов в массиве;
- при обращению к элементу массива указывается ИНДЕКС элемента в массиве;
- значение индекса изменяется от 0 до N-1 (N- кол-во элементов в массиве)
...но в данном случае можно обойтись одним массивом:
Dim $aIcons[2]=['error.ico','ok.ico']
$pic1_1=$aIcons[$sLog1_1=4]
$pic3_1=$aIcons[$sLog3_1=4]
$pic1_2=$aIcons[$sLog1_2=2]
_ImageGet()
saavaage
31-08-2010, 16:51
amel27, нельзя. Там разные условия:
для 1_1 и 3_1 - да, можно (состояние либо 4 либо 1)
для 1_2 и 3_2 - 2,3,4. Причем только 2 = ok.icon
для 2_2 - 2,3,4. Но только 2 и 3 = ok.ico
Поэтому одномерным не обойтись...
saavaage, когда условие в скобках истинно, выбирается 2-й элемент, иначе 1-й... тут главное логическое выражение правильно составить... ;)
saavaage
31-08-2010, 17:00
amel27,
немного запутался. У Вас:
Dim $aIcons[2]=['error.ico','ok.ico']
$pic1_1=$aIcons[$sLog1_1=4]
$pic3_1=$aIcons[$sLog3_1=4]
$pic1_2=$aIcons[$sLog1_2=2]
_ImageGet() »
т.е. массив из 2-х значений. А при присвоении переменным значений элементов, элементы имеют индексы 4 и 2. Как такое возможно? Я, наверно, неправильно понимаю технологию процесса. Можете последний вопрос немного"разжевать"?
Заранее благодарен
когда условие в скобках истинно, выбирается 2-й элемент, иначе 1-й »
а, если истинно 2 условия типа загрузки - авто и дефолт (т.е. 2 и 3)?
amel27, в принципе я, наконец понял. Вы имели ввиду, что если $sLog1_1=4, то выбирается ok.ico, иначе error.ico. Правильно?
код:
Dim $aIcons[2]=['error.ico','ok.ico']
$pic1_1=$aIcons[$sLog1_1=4]
$pic3_1=$aIcons[$sLog3_1=4]
$pic1_2=$aIcons[$sLog1_2=2]
$pic2_2=$aIcons[$sLog2_2=3 or $sLog2_2=2]
$pic3_2=$aIcons[$sLog3_2=2]
_ImageGet()
А как, все-таки, надо было написать в случае многомерного (мой неправильный вариант)?
при присвоении переменным значений элементов, элементы имеют индексы 4 и 2 »нет - только 0 и 1
выражение ($sLog1_1=4) равно 1 (True), когда значение $sLog1_1 равно 4, и 0 (False) во всех остальных случаях
а, если истинно 2 условия типа загрузки - авто и дефолт? »
$picx_x=$aIcons[(($sLogx_x=2) Or ($sLogx_x=3))]
saavaage
31-08-2010, 17:33
amel27, у меня вроде нормально отработал и такой вариант
$pic2_2=$aIcons[$sLog2_2=3 or $sLog2_2=2]
Нет, поспешил отчитаться.... Ваша правда. Спасибо Большое. Задача сокращения- оптимизации решена, благодаря Вам.
PS а как, все-таки, надо было написать в случае многомерного массива (мой неправильный вариант)
saavaage
31-08-2010, 18:04
Таким образом, оптимизированный/сокращенный код:
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <Icons.au3>
#include <WinAPI.au3>
Global $pic1_1, $pic3_1, $pic1_2, $pic2_2, $pic3_2, $sLogI1_1, $sLogI1_2, $sLogI2_2, $sLogI3_1, $sLogI3_2
Global $Save_Event, $Save_MU, $Save_BITS, $sLog1_2, $sLog2_2, $sLog3_2, $sLog1_1, $sLog3_1
Opt("GUIOnEventMode", 1)
$hMain_GUI = GUICreate("Диагностика и Настройка", 619, 442, 189, 122)
GUISetIcon('Windows.ico', 1)
GUISetFont(8.5, 400, 0, 'MS Shell Dlg')
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
$Tab1 = GUICtrlCreateTab(8, 16, 601, 377)
;;;; Hotfixes ;;;;
$HotfixErrors = GUICtrlCreateTabItem("HotfixErrors")
$Button_HotFixesUpdate = GUICtrlCreateButton("Обновить", 84, 400, 60, 33, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_HotFixesUpdate, "_HotFixes_Update")
; Работа со службами
GUICtrlCreateGroup("Службы, отвечающие за Автообновление", 16, 330, 370, 55)
GUICtrlCreateLabel("Автоматич. обновление", 24, 348, 75, 30, $BS_MULTILINE)
GUICtrlSetTip(-1, "тс - текущее состояние службы, тз - тип запуска службы")
GUICtrlCreateLabel("тс", 95, 348, 15, 15)
GUICtrlCreateLabel("тз", 95, 361, 15, 15)
GUICtrlCreateLabel("Фоновая Интел. Служба", 143, 348, 75, 30, $BS_MULTILINE)
GUICtrlCreateLabel("тз", 229, 361, 15, 15)
GUICtrlCreateLabel("Журнал Событий", 282, 348, 75, 30, $BS_MULTILINE)
GUICtrlCreateLabel("тс", 335, 348, 15, 15)
GUICtrlCreateLabel("тз", 335, 361, 15, 15)
; запуск и сбор информации о текущем состоянии служб
_ServicesStat()
$Button_StartOptim = GUICtrlCreateButton("Старт", 478, 342, 55, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_StartOptim, "_StartOptim")
$Button_Save = GUICtrlCreateButton("Сохранить", 400, 342, 65, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_Save, "_SaveOld")
GUICtrlSetState(-1, $GUI_FOCUS)
$Button_Restore = GUICtrlCreateButton("Откат", 545, 342, 55, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_Restore, "_RestoreOld")
GUICtrlCreateTabItem("")
GUISetState()
While 1
Sleep(100)
WEnd
Func CLOSEClicked()
Exit
EndFunc
;; Hotfixes Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; функция сохранения текущих настроек служб
Func _SaveOld()
GUICtrlSetState($Button_Save, $GUI_DISABLE)
Dim $aSvcState[5]=['boot','system','auto','demand','disabled']
$Save_MU = $aSvcState[$sLog1_2]
$Save_BITS = $aSvcState[$sLog2_2]
$Save_Event= $aSvcState[$sLog3_2]
sleep(1000)
GUICtrlSetState($Button_Save, $GUI_ENABLE)
EndFunc
; функция оптимизации настроек служб для запуска и работы MU
Func _StartOptim()
GUICtrlSetState($Button_StartOptim, $GUI_DISABLE)
RunWait('sc config BITS start= demand', '', @SW_HIDE)
RunWait('sc config wuauserv start= auto', '', @SW_HIDE)
RunWait('sc start wuauserv', '', @SW_HIDE)
RunWait('sc config EventLog start= auto', '', @SW_HIDE)
RunWait('sc start EventLog', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_StartOptim, $GUI_ENABLE)
EndFunc
; функция откат состояния служб к старым конфигурациям
Func _RestoreOld()
GUICtrlSetState($Button_Restore, $GUI_DISABLE)
RunWait('sc config eventlog start= ' & $Save_Event &'', '', @SW_HIDE)
RunWait('sc config wuauserv start= ' & $Save_MU &'', '', @SW_HIDE)
RunWait('sc config BITS start= ' & $Save_BITS &'', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_Restore, $GUI_ENABLE)
EndFunc
;~ ; функция кнопки "Обновить" обновление информации о текущем состоянии служб
Func _HotFixes_Update()
GUICtrlSetState($Button_HotFixesUpdate, $GUI_DISABLE)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_HotFixesUpdate, $GUI_ENABLE)
EndFunc
; функция сбора информации о текущем состоянии служб (используется SC и обработка полученного вывода через StringRegExpReplace)и вывод через иконки данной информации на форму)
Func _ServicesStat()
$sLog1_1 = ''
$sLog1_2 = ''
$sLog2_2 = ''
$sLog3_1 = ''
$sLog3_2 = ''
; запрос информации о состоянии служб (текущее состояние: работает или нет)
$hIPconfig1_1 = Run('sc query wuauserv', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig3_1 = Run('sc query eventlog', '', @SW_HIDE, $STDOUT_CHILD)
; запрос информации о типе запуска служб (авто, вручную, отключено)
$hIPconfig1_2 = Run('sc qc wuauserv', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig2_2 = Run('sc qc BITS', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig3_2 = Run('sc qc eventlog', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLogI1_1 &= StdoutRead($hIPconfig1_1)
$sLogI3_1 &= StdoutRead($hIPconfig3_1)
$sLogI1_2 &= StdoutRead($hIPconfig1_2)
$sLogI2_2 &= StdoutRead($hIPconfig2_2)
$sLogI3_2 &= StdoutRead($hIPconfig3_2)
If @error Then ExitLoop
Sleep(10)
WEnd
; фильтрация информации о службах
$sLog1_1 = StringRegExpReplace($sLogI1_1, "(?si).*STATE\D*(\d+).*", '\1')
$sLog3_1 = StringRegExpReplace($sLogI3_1, "(?si).*STATE\D*(\d+).*", '\1')
$sLog1_2 = StringRegExpReplace($sLogI1_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
$sLog2_2 = StringRegExpReplace($sLogI2_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
$sLog3_2 = StringRegExpReplace($sLogI3_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
; программиорование отображение информации о службах через иконки
Dim $aIcons[2]=['error.ico','ok.ico']
$pic1_1=$aIcons[$sLog1_1=4]
$pic3_1=$aIcons[$sLog3_1=4]
$pic1_2=$aIcons[$sLog1_2=2]
$pic2_2=$aIcons[(($sLog2_2 = 3) Or ($sLog2_2 = 2))]
$pic3_2=$aIcons[$sLog1_2=2]
_ImageGet()
EndFunc
; функция отображения иконок на конкрентой вкладке формы (форма с Tab)
Func _ImageGet()
$Width = 14
$Height = 14
$hIcon1_1 = _Icons_Icon_Extract($pic1_1, -3, $Width, $Height)
$hBitmap1_1 = _Icons_Bitmap_CreateFromIcon($hIcon1_1)
$Pic1_1 = GUICtrlCreatePic('', 115, 348, $Width, $Height)
_SetHImage(-1, $hBitmap1_1)
$hIcon3_1 = _Icons_Icon_Extract($pic3_1, -3, $Width, $Height)
$hBitmap3_1 = _Icons_Bitmap_CreateFromIcon($hIcon3_1)
$Pic3_1 = GUICtrlCreatePic('', 355, 348, $Width, $Height)
_SetHImage(-1, $hBitmap3_1)
$hIcon1_2 = _Icons_Icon_Extract($pic1_2, -3, $Width, $Height)
$hBitmap1_2 = _Icons_Bitmap_CreateFromIcon($hIcon1_2)
$Pic1_2 = GUICtrlCreatePic('', 115, 361, $Width, $Height)
_SetHImage(-1, $hBitmap1_2)
$hIcon2_2 = _Icons_Icon_Extract($pic2_2, -3, $Width, $Height)
$hBitmap2_2 = _Icons_Bitmap_CreateFromIcon($hIcon2_2)
$Pic2_2 = GUICtrlCreatePic('', 249, 361, $Width, $Height)
_SetHImage(-1, $hBitmap2_2)
$hIcon3_2 = _Icons_Icon_Extract($pic3_2, -3, $Width, $Height)
$hBitmap3_2 = _Icons_Bitmap_CreateFromIcon($hIcon3_2)
$Pic3_2 = GUICtrlCreatePic('', 355, 361, $Width, $Height)
_SetHImage(-1, $hBitmap3_2)
_WinAPI_DeleteObject($hBitmap1_1)
_WinAPI_DeleteObject($hBitmap3_1)
_WinAPI_DeleteObject($hBitmap1_2)
_WinAPI_DeleteObject($hBitmap2_2)
_WinAPI_DeleteObject($hBitmap3_2)
_WinAPI_DestroyIcon($hIcon1_1)
_WinAPI_DestroyIcon($hIcon3_1)
_WinAPI_DestroyIcon($hIcon1_2)
_WinAPI_DestroyIcon($hIcon2_2)
_WinAPI_DestroyIcon($hIcon3_2)
EndFunc
;; End Hotfixes Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
поспешил отчитаться »скобки в логических выражениях лишними не будут
как, все-таки, надо было написать в случае многомерного »где-то так:
Dim $aState1[3][5]=[ _
['error.ico','error.ico','ok.ico' ,'error.ico','error.ico'], _
['error.ico','error.ico','error.ico','error.ico','ok.ico' ], _
['error.ico','error.ico','ok.ico' ,'ok.ico' ,'error.ico']]
$pic1_2=$aState1[0][$sLog1_2]
$pic3_2=$aState1[0][$sLog3_2]
$pic1_1=$aState1[1][$sLog1_1]
$pic3_1=$aState1[1][$sLog3_1]
$pic2_2=$aState1[2][$sLog2_2]
_ImageGet()
saavaage
02-09-2010, 00:05
amel27, рано я радовался.
Неожиданно возникла проблема при добавлении вкладки "Devices" (в коде выделил жирным). При нажатии на кнопки "Обновить", "Старт" и "Откат" происходит "прорисовка" иконок на этой вкладке. Промучился весь день и никак не смог это разрешить. Понятно, что это происходит потому, что у меня в эти функции ( _HotFixes_Update(), _StartOptim() и _RestoreOld() ) вставлен запуск _ServicesStat() для обновления информации о службах и, соответственно, иконках. Если его (запуск) закомментировать, то все нормально, но тогда нет обновления иконок после этих операций (обновить, старт и откат).
Вот код:
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <Icons.au3>
#include <WinAPI.au3>
Global $pic1_1, $pic3_1, $pic1_2, $pic2_2, $pic3_2, $sLogI1_1, $sLogI1_2, $sLogI2_2, $sLogI3_1, $sLogI3_2
Global $Save_Event, $Save_MU, $Save_BITS, $sLog1_2, $sLog2_2, $sLog3_2, $sLog1_1, $sLog3_1
Opt("GUIOnEventMode", 1)
$hMain_GUI = GUICreate("Диагностика и Настройка", 619, 442, 189, 122)
GUISetFont(8.5, 400, 0, 'MS Shell Dlg')
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
$Tab1 = GUICtrlCreateTab(8, 16, 601, 377)
;;;; Hotfixes ;;;;
$HotfixErrors = GUICtrlCreateTabItem("HotfixErrors")
$Button_HotFixesUpdate = GUICtrlCreateButton("Обновить", 84, 400, 60, 33, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_HotFixesUpdate, "_HotFixes_Update")
; Работа со службами
GUICtrlCreateGroup("Службы, отвечающие за Автообновление", 16, 330, 370, 55)
GUICtrlCreateLabel("Автоматич. обновление", 24, 348, 75, 30, $BS_MULTILINE)
GUICtrlSetTip(-1, "тс - текущее состояние службы, тз - тип запуска службы")
GUICtrlCreateLabel("тс", 95, 348, 15, 15)
GUICtrlCreateLabel("тз", 95, 361, 15, 15)
GUICtrlCreateLabel("Фоновая Интел. Служба", 143, 348, 75, 30, $BS_MULTILINE)
GUICtrlCreateLabel("тз", 229, 361, 15, 15)
GUICtrlCreateLabel("Журнал Событий", 282, 348, 75, 30, $BS_MULTILINE)
GUICtrlCreateLabel("тс", 335, 348, 15, 15)
GUICtrlCreateLabel("тз", 335, 361, 15, 15)
; запуск и сбор информации о текущем состоянии служб
_ServicesStat()
$Button_StartOptim = GUICtrlCreateButton("Старт", 478, 342, 55, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_StartOptim, "_StartOptim")
$Button_Save = GUICtrlCreateButton("Сохранить", 400, 342, 65, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_Save, "_SaveOld")
GUICtrlSetState(-1, $GUI_FOCUS)
$Button_Restore = GUICtrlCreateButton("Откат", 545, 342, 55, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_Restore, "_RestoreOld")
;;; Devices ;;;
$DevicesErrors = GUICtrlCreateTabItem("DriversErrors")
GUICtrlCreateGroup("Список проблемного оборудования", 16, 48, 481, 337)
GUICtrlCreateTabItem("")
GUISetState()
While 1
Sleep(100)
WEnd
Func CLOSEClicked()
Exit
EndFunc
;; Hotfixes Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; функция сохранения текущих настроек служб
Func _SaveOld()
GUICtrlSetState($Button_Save, $GUI_DISABLE)
Dim $aSvcState[5]=['boot','system','auto','demand','disabled']
$Save_MU = $aSvcState[$sLog1_2]
$Save_BITS = $aSvcState[$sLog2_2]
$Save_Event= $aSvcState[$sLog3_2]
sleep(1000)
GUICtrlSetState($Button_Save, $GUI_ENABLE)
EndFunc
; функция оптимизации настроек служб для запуска и работы MU
Func _StartOptim()
GUICtrlSetState($Button_StartOptim, $GUI_DISABLE)
RunWait('sc config BITS start= demand', '', @SW_HIDE)
RunWait('sc config wuauserv start= auto', '', @SW_HIDE)
RunWait('sc start wuauserv', '', @SW_HIDE)
RunWait('sc config EventLog start= auto', '', @SW_HIDE)
RunWait('sc start EventLog', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_StartOptim, $GUI_ENABLE)
EndFunc
; функция откат состояния служб к старым конфигурациям
Func _RestoreOld()
GUICtrlSetState($Button_Restore, $GUI_DISABLE)
RunWait('sc config eventlog start= ' & $Save_Event &'', '', @SW_HIDE)
RunWait('sc config wuauserv start= ' & $Save_MU &'', '', @SW_HIDE)
RunWait('sc config BITS start= ' & $Save_BITS &'', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_Restore, $GUI_ENABLE)
EndFunc
;~ ; функция кнопки "Обновить" обновление информации о текущем состоянии служб
Func _HotFixes_Update()
GUICtrlSetState($Button_HotFixesUpdate, $GUI_DISABLE)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_HotFixesUpdate, $GUI_ENABLE)
EndFunc
; функция сбора информации о текущем состоянии служб (используется SC и обработка полученного вывода через StringRegExpReplace)и вывод через иконки данной информации на форму)
Func _ServicesStat()
$sLog1_1 = ''
$sLog1_2 = ''
$sLog2_2 = ''
$sLog3_1 = ''
$sLog3_2 = ''
; запрос информации о состоянии служб (текущее состояние: работает или нет)
$hIPconfig1_1 = Run('sc query wuauserv', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig3_1 = Run('sc query eventlog', '', @SW_HIDE, $STDOUT_CHILD)
; запрос информации о типе запуска служб (авто, вручную, отключено)
$hIPconfig1_2 = Run('sc qc wuauserv', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig2_2 = Run('sc qc BITS', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig3_2 = Run('sc qc eventlog', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLogI1_1 &= StdoutRead($hIPconfig1_1)
$sLogI3_1 &= StdoutRead($hIPconfig3_1)
$sLogI1_2 &= StdoutRead($hIPconfig1_2)
$sLogI2_2 &= StdoutRead($hIPconfig2_2)
$sLogI3_2 &= StdoutRead($hIPconfig3_2)
If @error Then ExitLoop
Sleep(10)
WEnd
; фильтрация информации о службах
$sLog1_1 = StringRegExpReplace($sLogI1_1, "(?si).*STATE\D*(\d+).*", '\1')
$sLog3_1 = StringRegExpReplace($sLogI3_1, "(?si).*STATE\D*(\d+).*", '\1')
$sLog1_2 = StringRegExpReplace($sLogI1_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
$sLog2_2 = StringRegExpReplace($sLogI2_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
$sLog3_2 = StringRegExpReplace($sLogI3_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
; программиорование отображение информации о службах через иконки
Dim $aIcons[2]=['error.ico','ok.ico']
$pic1_1=$aIcons[$sLog1_1=4]
$pic3_1=$aIcons[$sLog3_1=4]
$pic1_2=$aIcons[$sLog1_2=2]
$pic2_2=$aIcons[(($sLog2_2 = 3) Or ($sLog2_2 = 2))]
$pic3_2=$aIcons[$sLog1_2=2]
_ImageGet()
EndFunc
; функция отображения иконок на конкрентой вкладке формы (форма с Tab)
Func _ImageGet()
$Width = 14
$Height = 14
$hIcon1_1 = _Icons_Icon_Extract($pic1_1, -3, $Width, $Height)
$hBitmap1_1 = _Icons_Bitmap_CreateFromIcon($hIcon1_1)
$Pic1_1 = GUICtrlCreatePic('', 115, 348, $Width, $Height)
_SetHImage(-1, $hBitmap1_1)
$hIcon3_1 = _Icons_Icon_Extract($pic3_1, -3, $Width, $Height)
$hBitmap3_1 = _Icons_Bitmap_CreateFromIcon($hIcon3_1)
$Pic3_1 = GUICtrlCreatePic('', 355, 348, $Width, $Height)
_SetHImage(-1, $hBitmap3_1)
$hIcon1_2 = _Icons_Icon_Extract($pic1_2, -3, $Width, $Height)
$hBitmap1_2 = _Icons_Bitmap_CreateFromIcon($hIcon1_2)
$Pic1_2 = GUICtrlCreatePic('', 115, 361, $Width, $Height)
_SetHImage(-1, $hBitmap1_2)
$hIcon2_2 = _Icons_Icon_Extract($pic2_2, -3, $Width, $Height)
$hBitmap2_2 = _Icons_Bitmap_CreateFromIcon($hIcon2_2)
$Pic2_2 = GUICtrlCreatePic('', 249, 361, $Width, $Height)
_SetHImage(-1, $hBitmap2_2)
$hIcon3_2 = _Icons_Icon_Extract($pic3_2, -3, $Width, $Height)
$hBitmap3_2 = _Icons_Bitmap_CreateFromIcon($hIcon3_2)
$Pic3_2 = GUICtrlCreatePic('', 355, 361, $Width, $Height)
_SetHImage(-1, $hBitmap3_2)
_WinAPI_DeleteObject($hBitmap1_1)
_WinAPI_DeleteObject($hBitmap3_1)
_WinAPI_DeleteObject($hBitmap1_2)
_WinAPI_DeleteObject($hBitmap2_2)
_WinAPI_DeleteObject($hBitmap3_2)
_WinAPI_DestroyIcon($hIcon1_1)
_WinAPI_DestroyIcon($hIcon3_1)
_WinAPI_DestroyIcon($hIcon1_2)
_WinAPI_DestroyIcon($hIcon2_2)
_WinAPI_DestroyIcon($hIcon3_2)
EndFunc
Буду признателен за любую подсказку...
PS на всякий случай, прикрепил архив с иконками и Icons.au3 (без них скрипт не сработает!)
saavaage
04-09-2010, 12:26
Решение предложено Yashied на русском форуме http://autoit-script.ru/index.php/topic,2497.msg18794.html#msg18794
Вот адаптированный под мой скрипт код:
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <Icons.au3>
#include <WinAPI.au3>
Global $Pic1_1, $Pic3_1, $Pic1_2, $Pic2_2, $Pic3_2, $PicError, $sLogI1_1, $sLogI1_2, $sLogI2_2, $sLogI3_1, $sLogI3_2, $hIcon, $Width = 14, $Height = 14
Global $Save_Event, $Save_MU, $Save_BITS, $sLog1_2, $sLog2_2, $sLog3_2, $sLog1_1, $sLog3_1
Global $aIcons[2] = ['error.ico', 'ok.ico']
For $i = 0 To 1
$hIcon = _Icons_Icon_Extract($aIcons[$i], 0, $Width, $Height)
$aIcons[$i] = _Icons_Bitmap_CreateFromIcon($hIcon)
_WinAPI_DestroyIcon($hIcon)
Next
Opt("GUIOnEventMode", 1)
$hMain_GUI = GUICreate("Диагностика и Настройка", 619, 442, 189, 122)
GUISetFont(8.5, 400, 0, 'MS Shell Dlg')
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
$Tab1 = GUICtrlCreateTab(8, 16, 601, 377)
;;;; Hotfixes ;;;;
$HotfixErrors = GUICtrlCreateTabItem("HotfixErrors")
$Button_HotFixesUpdate = GUICtrlCreateButton("Обновить", 84, 400, 60, 33, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_HotFixesUpdate, "_HotFixes_Update")
; Работа со службами
GUICtrlCreateGroup("Службы, отвечающие за Автообновление", 16, 330, 370, 55)
GUICtrlCreateLabel("Автоматич. обновление", 24, 348, 75, 30, $BS_MULTILINE)
GUICtrlSetTip(-1, "тс - текущее состояние службы, тз - тип запуска службы")
GUICtrlCreateLabel("тс", 95, 348, 15, 15)
GUICtrlCreateLabel("тз", 95, 361, 15, 15)
GUICtrlCreateLabel("Фоновая Интел. Служба", 143, 348, 75, 30, $BS_MULTILINE)
GUICtrlCreateLabel("тз", 229, 361, 15, 15)
GUICtrlCreateLabel("Журнал Событий", 282, 348, 75, 30, $BS_MULTILINE)
GUICtrlCreateLabel("тс", 335, 348, 15, 15)
GUICtrlCreateLabel("тз", 335, 361, 15, 15)
$Pic1_1 = GUICtrlCreatePic('', 115, 348, $Width, $Height)
$Pic3_1 = GUICtrlCreatePic('', 355, 348, $Width, $Height)
$Pic1_2 = GUICtrlCreatePic('', 115, 361, $Width, $Height)
$Pic2_2 = GUICtrlCreatePic('', 249, 361, $Width, $Height)
$Pic3_2 = GUICtrlCreatePic('', 355, 361, $Width, $Height)
; запуск и сбор информации о текущем состоянии служб
_ServicesStat()
$Button_StartOptim = GUICtrlCreateButton("Старт", 478, 342, 55, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_StartOptim, "_StartOptim")
$Button_Save = GUICtrlCreateButton("Сохранить", 400, 342, 65, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_Save, "_SaveOld")
GUICtrlSetState(-1, $GUI_FOCUS)
$Button_Restore = GUICtrlCreateButton("Откат", 545, 342, 55, 35, $BS_MULTILINE)
GUICtrlSetOnEvent($Button_Restore, "_RestoreOld")
;;; Devices ;;;
$DevicesErrors = GUICtrlCreateTabItem("DriversErrors")
GUICtrlCreateGroup("Список проблемного оборудования", 16, 48, 481, 337)
GUICtrlCreateTabItem("")
GUISetState()
While 1
Sleep(100)
WEnd
Func CLOSEClicked()
Exit
EndFunc
;; Hotfixes Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; функция сохранения текущих настроек служб
Func _SaveOld()
GUICtrlSetState($Button_Save, $GUI_DISABLE)
Dim $aSvcState[5]=['boot','system','auto','demand','disabled']
$Save_MU = $aSvcState[$sLog1_2]
$Save_BITS = $aSvcState[$sLog2_2]
$Save_Event= $aSvcState[$sLog3_2]
sleep(1000)
GUICtrlSetState($Button_Save, $GUI_ENABLE)
EndFunc
; функция оптимизации настроек служб для запуска и работы MU
Func _StartOptim()
GUICtrlSetState($Button_StartOptim, $GUI_DISABLE)
RunWait('sc config BITS start= demand', '', @SW_HIDE)
RunWait('sc config wuauserv start= auto', '', @SW_HIDE)
RunWait('sc start wuauserv', '', @SW_HIDE)
RunWait('sc config EventLog start= auto', '', @SW_HIDE)
RunWait('sc start EventLog', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_StartOptim, $GUI_ENABLE)
EndFunc
; функция откат состояния служб к старым конфигурациям
Func _RestoreOld()
GUICtrlSetState($Button_Restore, $GUI_DISABLE)
RunWait('sc config eventlog start= ' & $Save_Event &'', '', @SW_HIDE)
RunWait('sc config wuauserv start= ' & $Save_MU &'', '', @SW_HIDE)
RunWait('sc config BITS start= ' & $Save_BITS &'', '', @SW_HIDE)
sleep(1000)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_Restore, $GUI_ENABLE)
EndFunc
; функция кнопки "Обновить" обновление информации о текущем состоянии служб
Func _HotFixes_Update()
GUICtrlSetState($Button_HotFixesUpdate, $GUI_DISABLE)
_ServicesStat()
sleep(1000)
GUICtrlSetState($Button_HotFixesUpdate, $GUI_ENABLE)
EndFunc
; функция сбора информации о текущем состоянии служб (используется SC и обработка полученного вывода через StringRegExpReplace)и вывод через иконки данной информации на форму)
Func _ServicesStat()
$sLog1_1 = ''
$sLog1_2 = ''
$sLog2_2 = ''
$sLog3_1 = ''
$sLog3_2 = ''
; запрос информации о состоянии служб (текущее состояние: работает или нет)
$hIPconfig1_1 = Run('sc query wuauserv', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig3_1 = Run('sc query eventlog', '', @SW_HIDE, $STDOUT_CHILD)
; запрос информации о типе запуска служб (авто, вручную, отключено)
$hIPconfig1_2 = Run('sc qc wuauserv', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig2_2 = Run('sc qc BITS', '', @SW_HIDE, $STDOUT_CHILD)
$hIPconfig3_2 = Run('sc qc eventlog', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLogI1_1 &= StdoutRead($hIPconfig1_1)
$sLogI3_1 &= StdoutRead($hIPconfig3_1)
$sLogI1_2 &= StdoutRead($hIPconfig1_2)
$sLogI2_2 &= StdoutRead($hIPconfig2_2)
$sLogI3_2 &= StdoutRead($hIPconfig3_2)
If @error Then ExitLoop
Sleep(10)
WEnd
; фильтрация информации о службах
$sLog1_1 = StringRegExpReplace($sLogI1_1, "(?si).*STATE\D*(\d+).*", '\1')
$sLog3_1 = StringRegExpReplace($sLogI3_1, "(?si).*STATE\D*(\d+).*", '\1')
$sLog1_2 = StringRegExpReplace($sLogI1_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
$sLog2_2 = StringRegExpReplace($sLogI2_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
$sLog3_2 = StringRegExpReplace($sLogI3_2, "(?si).*START_TYPE\D*(\d+).*", '\1')
; программиорование отображение информации о службах через иконки
_SetHImage($Pic1_1, $aIcons[$sLog1_1 = 4])
_SetHImage($Pic3_1, $aIcons[$sLog3_1=4])
_SetHImage($Pic1_2, $aIcons[$sLog1_2=2])
_SetHImage($Pic2_2, $aIcons[(($sLog2_2 = 3) Or ($sLog2_2 = 2))])
_SetHImage($Pic3_2, $aIcons[$sLog3_2=2])
_SetHImage($PicError, $aIcons[$sLog3_1=4])
EndFunc
Т.о. тема решена. Еще раз спасибо за помощь amel27 и Yashied.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.