Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Некорректно отрабатывает скрипт финализации (http://forum.oszone.net/showthread.php?t=181869)

saavaage 01-08-2010 01:12 1464348

Некорректно отрабатывает скрипт финализации
 
Стоит задача по созданию скрипта финализации, который будет запускается после установки Win XP при первом входе в систему (после загрузки рабочего стола).
Его задача: блокирование ПК, создание и запуск батника по очистке системы, самоуничтожение и перезагрузка ПК после окончания отработки. Кроме того, требуется, чтобы во-время отработки скрипта было окно с прогресс-баром (с заданием обратного таймера).
Реализация:
1. файл по закидыванию в автозагрузку (FinishReady.cmd):
Код:

@echo off
rem помещение в автозагрузку finish.exe
REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v finish /t REG_SZ /d %SYSTEMDRIVE%\finish.exe"
EXIT

1. Сам скрипт (finish.exe):
Код:

;Предотвращение появление процесса-клона
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)

;Блокирование ПК
#NoTrayIcon
#include <BlockInputEx.au3>
Opt("WinWaitDelay", 1)
$sTaskMgr_Title = "[CLASS:#32770;REGEXPTITLE:(Диспетчер задач|Task Manager)]"
;Disable Task Manager
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", "REG_DWORD", "1")
_BlockInputEx(1)

;считывание из cleanup.txt времени отработки прогресс-бара и передача этого значения в  переменную $line
$file = FileOpen("cleanup.txt", 0)
; Read in lines of text
$line = FileReadLine($file, 2)
FileClose($file)
Sleep(1000)
; переименование cleanup.txt в cleanup.cmd
FileMove("cleanup.txt", "cleanup.cmd")
Sleep(3000)

$iPID = Run(@COMSPEC & ' /c %SYSTEMDRIVE%\cleanup.cmd', "", @SW_HIDE)
While ProcessExists($iPID)
$Title = "Пожалуйста, подождите..."            ; Заголовок
$SubTitle = "Происходит финализация установки"  ; Суб-заголовок
$Message  = "После удаления мусора, оставшегося от установки" & @CRLF ; Сообщение. Записано в таком виде для удобства
$Message &= "XP и создания/перемещения ярлыков, Система" & @CRLF
$Message &= "будет перезагружена. Осталось времени: "

$Time = $line      ; Время здесь хранится в миллескундах. 1 с = 1000 мс

$Sleep = 0.01 * 100000    ; 10 мс. Меньше 1 мс ставить не рекомундуется. Впрочем, тут и 100 мс хватает.

$Timer = TimerInit() ; Инициализация таймера.

ProgressOn($Title, $SubTitle, $Message & $Time) ; Параметры: заголовок, суб-заголовок, сообщение. Включаем окно прогресса.
While TimerDiff($Timer) < $Time ; Пока прошло времени меньше чем нужно - повторять:
    ProgressSet(TimerDiff($Timer) / $Time * 100, $Message & Round(($Time - TimerDiff($Timer)) / 1000, 0) & " секунд")
    ; ProgressSet ( percent [, "subtext" [, "maintext"]] )
    ; Параметр 1: процент прогресса. Прошедшее время делим на требуемое и умножаем на 100
    ; Параметр 2: сообщение. Стандартное, как в перменной $Message плюс оставшееся время округлённое до целых
    ; Параметр 3: опциональный. Здесь не используется.
    Sleep($Sleep); Подожать $Sleep мс
WEnd
WEnd
ProgressSet(100, "ПЕРЕЗАГРУЗКА!  УДАЧНОЙ  РАБОТЫ!") ; Выводим последнее сообщение.
Sleep(3000) ; Чтобы было видно последнее сообщение.

;Enable Task Manager back
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", "REG_DWORD", "0")

; Функция самоудалениея скрипта
#Include <File.au3>
Func _ScriptDestroy()
    $sTemp = _TempFile(@TempDir, '~', '.bat')
    $sPath = FileGetShortName(@ScriptFullPath)
    $hFile = FileOpen($sTemp, 2)
    FileWriteLine($hFile, '@echo off')
    FileWriteLine($hFile, ':loop')
    FileWriteLine($hFile, 'del ' & $sPath)
    FileWriteLine($hFile, 'if exist ' & $sPath & ' goto loop')
    FileWriteLine($hFile, 'del ' & $sTemp)
    FileClose($hFile)
    Run($sTemp, '', @SW_HIDE)
EndFunc  ;==>_ScriptDestroy

_ScriptDestroy()

Sleep(1000)
Shutdown(2)

3. Все настройки по очистке, приведению в порядок меню "Пуск" и времени (n секунд ) отработки прогресс-бара берутся из файла cleanup.txt:
Код:

rem задание времени отработки прогресс-бара (1000 = 1 секунда)
60000

rem Удаление из автозагрузки finish
Reg Delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v finish /f

rem Удаление мусора после установки Системы

rem Очистка рабочего стола от ярлыков
DEL /F /Q "%AllUsersProfile%\Рабочий стол\*.*"
del /f /q "%UserProfile%\Рабочий стол\*.*"
DEL /F /Q "%systemdrive%\Documents and Settings\Default User\Рабочий стол\*.*"

rem Удаление мусора и папок Temp, Tmp и проч.

PUSHD %TEMP%
2>Nul RD /S /Q "%TEMP%"
POPD

RD /s /q "%WINDIR%\Temp\*.*"
rem RD /S /Q "%SYSTEMDRIVE%\D\"
del /s /f /q "%UserProfile%\Избранное\Ссылки\*.*"
RD /S /Q "%WINDIR%\I386\SVCPACK\"
rem RD /S /Q "%WINDIR%\OemDrv\"

rem Создание Temp в корне системного раздела и назначение полного доступа
md %systemdrive%\Temp
Echo Y | Cacls %SystemRoot%\Temp /E /P "Все":F

rem переназначение всех temp и tmp на созданную папку Temp в корне системного раздела
reg add "HKLM\SYSTEM\ControlSet\Control\Session Manager\Environment" /v "TEMP" /t REG_SZ /d %systemdrive%\Temp /f
reg add "HKLM\SYSTEM\ControlSet\Control\Session Manager\Environment" /v "TMP" /t REG_SZ /d %systemdrive%\Temp /f
reg add "HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment" /v "TEMP" /t REG_SZ /d %systemdrive%\Temp /f
reg add "HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment" /v "TMP" /t REG_SZ /d %systemdrive%\Temp /f
reg add "HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment" /v "TEMP" /t REG_SZ /d %systemdrive%\Temp /f
reg add "HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment" /v "TMP" /t REG_SZ /d %systemdrive%\Temp /f

reg add "HKCU\Environment" /v "TMP" /t REG_SZ /d %systemdrive%\Temp /f
reg add "HKCU\Environment" /v "TEMP" /t REG_SZ /d %systemdrive%\Temp /f

rem Удаление пользователя созданного .NET Framework 1.1...
net user aspnet /delete

rem Создание групп ярлыков в Меню Программы
mkdir "%Userprofile%\Главное меню\Программы\Утилиты"
mkdir "%Userprofile%\Главное меню\Программы\Интернет"
mkdir "%Userprofile%\Главное меню\Программы\Мультимедиа\Прожиг"
mkdir "%Userprofile%\Главное меню\Программы\Игры"
mkdir "%Userprofile%\Главное меню\Программы\Система"

rem Перемещение-удаление ярлыков
rem Интернет
move "%Allusersprofile%\Главное меню\Программы\Opera.lnk" "%userprofile%\Главное меню\Программы\Интернет"
move "%Userprofile%\Главное меню\Программы\Internet Explorer.lnk" "%userprofile%\Главное меню\Программы\Интернет"
move "%Userprofile%\Главное меню\Программы\Удаленный помощник.lnk" "%userprofile%\Главное меню\Программы\Интернет"
DEL /q "%UserProfile%\Application Data\Microsoft\Internet Explorer\Quick Launch\Запустить обозреватель Internet Explorer.lnk"
rem Мультимедиа
move "%AllUsersprofile%\Главное меню\Программы\Утилиты\Запись CD-DVD\CDBurnerXP.lnk" "%userprofile%\Главное меню\Программы\Мультимедиа\Прожиг"
;move "%AllUsersprofile%\Главное меню\Программы\Запись дисков и образов.lnk" "%userprofile%\Главное меню\Программы\Мультимедиа\Прожиг"
rd /S /Q "%Allusersprofile%\Главное меню\Программы\Утилиты\Запись CD-DVD"
move "%Userprofile%\Главное меню\Программы\Windows Media Player.lnk" "%userprofile%\Главное меню\Программы\Мультимедиа"
rem Утилиты
move "%AllUsersprofile%\Главное меню\Программы\WinRAR" "%userprofile%\Главное меню\Программы\Утилиты"
rd /S /Q "%Userprofile%\Главное меню\Программы\WinRAR"
move "%AllUsersprofile%\Главное меню\Программы\7-Zip" "%userprofile%\Главное меню\Программы\Утилиты"
move "%Userprofile%\Главное меню\Программы\7ztools" "%userprofile%\Главное меню\Программы\Утилиты"
move "%Userprofile%\Главное меню\Программы\SuperCopier2" "%userprofile%\Главное меню\Программы\Утилиты"
rem Система
move "%AllUsersprofile%\Главное меню\Программы\Утилиты\Piriform" "%userprofile%\Главное меню\Программы\Система"

rem самоуничтожение после отработки
DEL /F /Q %0

Суть проблемы:
при старте скрипта из автозагрузки отработка происходит некорректным образом (скрипт даже не успевает переименовать cleanup.txt в cleanup.cmd)
если же запускаю вручную (дабл-клик по finish.exe), то все проходит штатно.
Где я ошибся? Finish.exe и cleanup.txt располагаются в корне раздела С


PS На всякий случай прикрепляю все 3 файла

Creat0R 01-08-2010 02:04 1464375

Цитата:

Цитата saavaage
отработка происходит некорректным образом »

А подробнее, скрипт вываливается с ошибками? вообще для отладки не помешало бы поставить MsgBox в потенциально проблематичных местах.

saavaage 01-08-2010 02:38 1464385

Creat0R,
1. когда скрипт запускаешь вручную, то все отрабатывает как следует:
система блокируется -> из cleanup.txt вытягивается время отработки прогресс-бара и передается в переменную $line -> cleanup.txt переименовывается в cleanup.cmd -> возникает окно спрогресс-баром + идет отработка cleanup.cmd -> заканчивается прогресс-бар + возникает предупреждение о перезагрузки -> скрипт самоуничтожается -> система перезагружается.
Все отрабатывает штатно.

2. если же скрипт запустить из-под автозагрузки, то после появления рабочего стола , я успеваю увидеть только напоминание-предупреждение о перезагрузки -> скрипт самоуничтожается -> система перезагружается.
После перезагрузки я вижу, что файл cleanup.txt так и остался непереименованным и,соответсвенно, он не отработал. Поэтому, имхо, и прогресс-бар так и не появился (насколько я понимаю, он привязан к отработке cleanup.cmd). Могу только предположить, что ошибка закралась где-то здесь:
Код:

;считывание из cleanup.txt времени отработки прогресс-бара и передача этого значения в  переменную $line
$file = FileOpen("cleanup.txt", 0)
; Read in lines of text
$line = FileReadLine($file, 2)
FileClose($file)
Sleep(1000)
; переименование cleanup.txt в cleanup.cmd
FileMove("cleanup.txt", "cleanup.cmd")
Sleep(3000)

Мне необходимо, чтобы скрипт отрабатывал именно из-под автозагрузки...

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

Да, забыл упомянуть, что тестирование проходит из-под виртуалбокса. Может в нем собака порылась? Завтра проверю на живой...

saavaage 01-08-2010 10:19 1464431

Проверил на живой. Вообще не увидел месседж-бокса. Система после загрузки, ушла на перезагрузку. После нее, зашел на С и увидел, что finish.exe удален, а cleanup.txt остался не переименнованным. Запуск вручную - все проходит штатно.

Уфф, все отработало из-под автозагрузки после следующей модификации кода в предыдущем посте.

Код:

;считывание из cleanup.txt времени отработки прогрессбара и передача этого значения в  переменную $line
$line = FileReadLine(@ScriptDir & "\cleanUp.cmd", 2)

Итого, рабочий скрипт:

Код:

;Предотвращение появление процесса-клона
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)

;Блокирование ПК
#NoTrayIcon
#include <BlockInputEx.au3>
Opt("WinWaitDelay", 1)
$sTaskMgr_Title = "[CLASS:#32770;REGEXPTITLE:(Диспетчер задач|Task Manager)]"
;Disable Task Manager
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", "REG_DWORD", "1")
_BlockInputEx(1)

;считывание из cleanup.txt времени отработки прогрессбара и передача этого значения в  переменную $line
$line = FileReadLine(@ScriptDir & "\cleanUp.cmd", 2)

$iPID = Run(@COMSPEC & ' /c %SYSTEMDRIVE%\cleanup.cmd', "", @SW_HIDE)
While ProcessExists($iPID)
$Title = "Пожалуйста, подождите..."            ; Заголовок
$SubTitle = "Происходит финализация установки"  ; Суб-заголовок
$Message  = "После удаления мусора, оставшегося от установки" & @CRLF ; Сообщение. Записано в таком виде для удобства
$Message &= "XP и создания/перемещения ярлыков, Система" & @CRLF
$Message &= "будет перезагружена. Осталось времени: "

$Time = $line      ; Время здесь хранится в миллескундах. 1 с = 1000 мс

$Sleep = 0.01 * 100000    ; 10 мс. Меньше 1 мс ставить не рекомундуется. Впрочем, тут и 100 мс хватает.

$Timer = TimerInit() ; Инициализация таймера.

ProgressOn($Title, $SubTitle, $Message & $Time) ; Параметры: заголовок, суб-заголовок, сообщение. Включаем окно прогресса.
While TimerDiff($Timer) < $Time ; Пока прошло времени меньше чем нужно - повторять:
    ProgressSet(TimerDiff($Timer) / $Time * 100, $Message & Round(($Time - TimerDiff($Timer)) / 1000, 0) & " секунд")
    ; ProgressSet ( percent [, "subtext" [, "maintext"]] )
    ; Параметр 1: процент прогресса. Прошедшее время делим на требуемое и умножаем на 100
    ; Параметр 2: сообщение. Стандартное, как в перменной $Message плюс оставшееся время округлённое до целых
    ; Параметр 3: опциональный. Здесь не используется.
    Sleep($Sleep); Подожать $Sleep мс
WEnd
WEnd
ProgressSet(100, "ПЕРЕЗАГРУЗКА!  УДАЧНОЙ  РАБОТЫ!") ; Выводим последнее сообщение.
Sleep(3000) ; Чтобы было видно последнее сообщение.

;Enable Task Manager back
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", "REG_DWORD", "0")

; Функция самоудалениея скрипта
#Include <File.au3>
Func _ScriptDestroy()
    $sTemp = _TempFile(@TempDir, '~', '.bat')
    $sPath = FileGetShortName(@ScriptFullPath)
    $hFile = FileOpen($sTemp, 2)
    FileWriteLine($hFile, '@echo off')
    FileWriteLine($hFile, ':loop')
    FileWriteLine($hFile, 'del ' & $sPath)
    FileWriteLine($hFile, 'if exist ' & $sPath & ' goto loop')
    FileWriteLine($hFile, 'del ' & $sTemp)
    FileClose($hFile)
    Run($sTemp, '', @SW_HIDE)
EndFunc  ;==>_ScriptDestroy

_ScriptDestroy()

Sleep(1000)
Shutdown(2)


Creat0R 01-08-2010 14:28 1464573

Цитата:

Цитата saavaage
все отработало из-под автозагрузки после следующей модификации кода в предыдущем посте »

Всё верно, полные пути необходимы, т.к при запуске из автозагрузки рабочий каталог это скорее всего системный каталог.


Время: 14:42.

Время: 14:42.
© OSzone.net 2001-