1 (изменено: Androgen, 2007-07-11 06:52:33)

Тема: AutoHotkey: обновлялка для DrWeb

Мне в качестве антивируса нравится DrWeb. И, разумеется, он имеет свою собственную обновлялку. Но многих, я знаю, она не устаивает. Кого-то потому, что не любит когда неизвестно кто качает и передаёт неизвестно что. Кого-то потому, что после "официального" обновления слетает "неправедная" регистрация. А кто-то хочет сэкономить трафик.
Вот в сети и существует немалое количество альтернативных обновлялок. Несколькими я пробовал пользоваться. Но ни одна из тех, что я юзал, не работала так, как мне было нужно (а иные и вовсе безбожно глючили).
Руководствуясь известной сентенцией "если хочешь, чтобы всё было как надо - сделай это сам" я и накатал свою обновлялку. Было это года два назад. С тех пор я её постоянно корректировал в связи с:
- изменениями в DrWeb'е и форме получения обновлений;
- эксплуатацией обновлялки моими друзьями и знакомыми;
- усилением возможностей AutoHotkey.
Короче, скрипт протестирован "будь здоров". Учтено множество разных разностей. Этим объясняется, как может показаться, избыточность вводных данных (настроек пользователя) и прочих всяких проверок. Зато теперь, при необходимости или желании, легко изменять поведение скрипта. Для этих целей в скрипте и оставлены отладочные строки. Однако можно ничего не настраивать и скрипт будет работать правильно и сразу (хочется верить).
Скрипт заточен под компиляцию (хотя это и необязательно). Перед компиляцией, рядом со скриптом нужно положить unzip.exe (его легко можно найти обычным поиском по вашему компьютеру или в сети). Готовый экзешник нужно положить в папку DrWeb'а. Более детальные комментарии можно найти внутри скрипта.

;*************************************************************************************************************
; AutoHotkey Version:   1.0.46.15+
; Автор:                Androgen Belkin
; Имя скрипта:          DrwUpdater.ahk (v.2.3)
;*************************************************************************************************************
; Обновление баз антивируса DrWeb.
; Скрипт нужно поместить в папку с файлами антивирусных баз
; (обычно базы лежат в папке с самим DrWeb'ом).
; Обновления (после загрузки) распакуются в папку с этим скриптом.
; Если скрипт будет находиться в папке DrWeb, то помимо баз
; будет проверяться и обновляться версия движка (drweb32.dll) и другие библиотеки.
;
; Скрипт использует встроенную в винду утилиту ftp.exe.
; Также используется UnZip.exe, который нужно положить рядом со скриптом.
; Я использую UnZip потому, что после компиляции скрипта
; он уже не зависит от наличия установленных распаковщиков.
;
; Разумеется, можно использовать и другой подходящий распаковщик, например, WinRar.
; Но тогда:
;     - нужно изменить командную строку распаковщика (она приведена и закомментирована).
;     - команду на листинг архива
;     - рассмотреть уместность команды FileInstall и пяти последующих строчек.
; Короче, использовать UnZip проще. И он значительно меньше размером :)
;
; Работа скрипта проверялась, в основном, на WinXP. Но будет работать и на Win9x.
; Правда тогда не будут показываться всплывающие сообщения, но это на работу скрипта не влияет.
;
; Для отладки скрипта, используются строки со словом "ОТЛАДКА!!!".
;*************************************************************************************************************
#NoEnv    ; запрещаем имена переменных как у переменных окружения

; ОТЛАДКА!!! Назначаем рабочую папку скрипта
;~ SetWorkingDir, %A_ProgramFiles%\DrWeb ; чтобы скрипт можно было держать в любом месте

;=============================================================================================================
; НАСТРОЙКИ ПОЛЬЗОВАТЕЛЯ:
Downloads_Dir = %A_Temp%\!DrwUpd ; куда ВРЕМЕННО закачивать архивы антивирусных баз (здесь их можно хранить)
Log_File = %A_WorkingDir%\DrwUpdater.log ; имя лога обновлений (можно не указывать, тогда он и не пишется)

; Файлы, у которых нужно проверять версии:
; Версии уже имеющихся баз проверяются по соответствующему файлу описания базы (например, drwtoday.txt).
; Если файла с описанием не существует, то база будет загружена безоговорочно (без проверки версии).
Check_Vers_vdb =
( LTrim Join| Comments ; LTrim - удалять пробелы в начале, соединять строки через "|", разрешить комменты
    drwtoday ; свежие обновления
    dwntoday ; nasty
    dwrtoday ; risky
    drwnasty ; базовый nasty
    drwrisky ; базовый risky
;~     drwebase.vdb ; не имеет файла описания, и его версия не проверяется т.к. он не изменяется
)

; Библиотеки, у которых нужно проверять версии (версия берётся из них самих)
; Поскольку количество библиотек периодически меняется, возможно понадобится корректировать этот список.
Check_Vers_dll =
( LTrim Join| Comments
    drweb32  ; движок
    vrcpp    ; спамовый фильтр
)

; теоретически могущие измениться "константы"
FTP_DrWeb = ftp.drweb.com ; адрес FTP-сервера DrWeb
FTP_Dir = pub/drweb/bases ; каталог на сервере, откуда будем брать базы
Base_List = info.txt ; имя файла на сервере со списком доступных к загрузке баз

; временные служебные файлы
New_Base_List = %Downloads_Dir%\DrWeb_New_Base.htm ; имя, под которым сохранять закачанный список баз
FTPCommandFile = %Downloads_Dir%\FTPCommands.txt ; имя временного файла для команд FTP
FTPLogFile = %Downloads_Dir%\FTPLog.txt ; имя временного файла для лога команд FTP
ArcList = %Downloads_Dir%\ArcList.txt ; имя временного файла для листинга архива

; файлы, которые нужно удалить по окончании работы скрипта
Del_Base := False ; удалять ли скачанные архивы
Del_Temp_Files = ; список удаляемых временных файлов
( LTrim Join| Comments
    %FTPCommandFile%
    %FTPLogFile%
    %ArcList%
    %Downloads_Dir%\UnZip.exe
;~     %New_Base_List%
)

; Ниже можно указать путь к ftp.exe. А можно не указывать, скорее всего этот файл есть в системе.
; Тогда он будет найден. Но я всё же оставил возможность указать путь. Так, на всякий случай.
;~ FTP_Exe = %A_ScriptDir%\ftp.exe ; путь к ftp.exe
; КОНЕЦ НАСТРОЕК ПОЛЬЗОВАТЕЛЯ
;=============================================================================================================


;=============================================================================================================
; ПРОВЕРИТЬ ПРАВИЛЬНОСТЬ ПУТИ ЗАПУСКА ОБНОВЛЯЛКИ (НАЛИЧИЕ АНТИВИРУСНЫХ БАЗ В ТЕКУЩЕЙ ПАПКЕ ПО МАСКЕ "*.vdb")
IfNotExist, *.vdb ; если файлы не найдены
{
    MsgBox,, Неверная папка запуска!, ; показать сообщение
    ( LTrim
        Поместите файл "%A_ScriptName%" в папку,
        в которой находятся антивирусные базы.
        Обычно это: "C:\Program Files\DrWeb".
    )
    ExitApp ; конец скрипта
}

; ПРОВЕРИТЬ СУЩЕСТВОВАНИЕ ПАПКИ, В КОТОРУЮ ВРЕМЕННО ЗАКАЧИВАЮТСЯ АРХИВЫ
IfNotExist, %Downloads_Dir% ; если папка не существует
{
    FileCreateDir, %Downloads_Dir% ; пробуем создать папку
    If ErrorLevel ; если папка не создалась (например, в настройках пользователя указан неверный путь)
    {
        MsgBox,, Внимание!, ; показать сообщение
        ( LTrim
            Не могу создать папку для временных файлов:
            "%Downloads_Dir%"`n
            Без этого обновление не может быть выполнено!
        )
        ExitApp ; конец скрипта
    }
}

; ПРОВЕРИТЬ НАЛИЧИЕ FTP.EXE по указанному пути ИЛИ В СИСТЕМЕ
IfNotExist, %FTP_Exe% ; если ftp.exe нет по указанному пути
{
    FTP_Exe := FileExistInShell("ftp.exe") ; ищем ftp.exe в системе
    If NOT FTP_Exe
    {
        MsgBox,, Внимание!, ; показать сообщение
        ( LTrim
            Не найден файл "ftp.exe".
            Он необходим, для загрузки обновлений.`n
            Без него обновление не может быть выполнено!
        )
        ExitApp ; конец скрипта
    }
}

;=============================================================================================================
; ПОЛУЧИТЬ СПИСОК НОВЫХ БАЗ
;~ /* ; ОТЛАДКА!!! НЕ ИДЁМ В ИНТЕРНЕТ (для отладки РАСкомментировать строчку, и её пару)

TrayTipText = Загружаю список антивирусных баз ; текст сообщения в трее
SetTimer, RefreshTrayTip, 1000 ; обновлять сообщение каждую секунду
Gosub, RefreshTrayTip ; показать сообщение в трее прямо сейчас

FileDelete, %FTPCommandFile% ; удаляем (возможно) оставшийся от предыдущих операций временный файл
FileDelete, %FTPLogFile% ; удаляем (возможно) оставшийся от предыдущих операций временный файл

; ПОЛУЧИТЬ СПИСОК НОВЫХ БАЗ
FileAppend, ; пишем команды FTP в файл
(LTrim Comments
    open %FTP_DrWeb% ; сервер DrWeb'а
    anonymous ; входить анонимно
    binary ; бинарный режим передачи
    get %FTP_Dir%/%Base_List% "%New_Base_List%" ; что и куда качаем
    quit ; выход из FTP-режима
), %FTPCommandFile%
RunWait, %comspec% /c "%FTP_Exe% -s:"%FTPCommandFile%" > "%FTPLogFile%"",, Hide

; ПРОВЕРИТЬ НАЛИЧИЕ ПОДКЛЮЧЕНИЯ К ИНТЕРНЕТ (анализируем лог)
FileReadLine, FirstLine, %FTPLogFile%, 1
If InStr(FirstLine, FTP_DrWeb) ; если была ошибка соединения
{
    MsgBox,, Внимание!, ; показать сообщение
    ( LTrim
        Не могу выполнить обновление!`n
        Возможно, нет подключения к Интернет.
        Попробуйте запустить обновление позже.
    )
    Goto, Del_Temp ; идём удалять временные файлы (конец скрипта)
}
;~ */ ; ОТЛАДКА!!! НЕ ИДЁМ В ИНТЕРНЕТ (для отладки РАСкомментировать строчку, и её пару)


;=============================================================================================================
; ИЩЕМ НОВЫЕ БАЗЫ, СРАВНИВАЕМ С ИМЕЮЩИМИСЯ
IfNotExist, %New_Base_List% ; если скачанный файл почему-то не существует
{
    MsgBox,, Внимание!, ; показать сообщение
    ( LTrim
        Не найден загруженный с сервера DrWeb список баз "%New_Base_List%".
        Возможно, во время обновления вы очистили папку "%Downloads_Dir%".`n
        Обновление не может быть завершено!
    )
    Goto, Del_Temp ; идём удалять временные файлы (конец скрипта)
}

Loop, read, %New_Base_List% ; лопатим загруженный список баз
{
    IfNotInString, A_LoopReadLine, %FTP_Dir% ; если в строке нет ссылки на архив
        Continue ; читаем следующую строку
    Base_Found := True ; флаг, что архивы в списке были найдены (чтобы знать, если обновлять ничего не надо)
    RegExMatch(A_LoopReadLine, FTP_Dir "/(\S+).zip", Arc_Name), Arc_Name := Arc_Name1 ; выкусываем имя архива

    Loop, parse, Check_Vers_vdb, | ; парсим список баз, требующих проверки версии
    {
        If Arc_Name = %A_LoopField% ; если база из тех, что требуют проверки версии
        {
            If NOT FileExist(Arc_Name ".txt") ; если описания базы или её самой не существует
            OR NOT FileExist(Arc_Name ".vdb")
                Goto, Add_To_Downloads ; добавляем базу в список безоговорочно (без проверки версии)
            ; описание существует, сравниваем версии имеющейся и новой баз
            FileReadLine, SecondLine, %Arc_Name%.txt, 2 ; читаем вторую строку файла с описанием базы
            RegExMatch(SecondLine, "\d+", Exist_Vers) ; получаем число записей в текущей базе
            RegExMatch(A_LoopReadLine, "(\d+)\)$", New_Vers_vdb) ; получаем число запсей в новой базе
            New_Vers_vdb := New_Vers_vdb1 ; берём нужную группу из RegExp'а
            If (Exist_Vers != New_Vers_vdb1) ; если версии не совпадают
                Goto, Add_To_Downloads ; добавляем базу в список загрузки
        }
    }
    Loop, parse, Check_Vers_dll, | ; парсим список dll, требующих проверки версии
    {
        If Arc_Name = %A_LoopField% ; если архив из тех, что требуют проверки версии
        {
            If NOT FileExist("drweb386.exe") ; (базы лежат отдельно от DrWeb)
                Goto, ContinueRead ; продолжить читать строки из списка баз

            ; dll существует, сравниваем версии имеющейся и новой dll
            FileGetVersion, Exist_Vers_dll, %A_LoopField%.dll
            RegExMatch(A_LoopReadLine, "\((\S+)\)$", New_Vers_dll ) ; получаем версию новой dll
            New_Vers_dll := New_Vers_dll1 ; берём нужную группу из RegExp'а
            If (Exist_Vers_dll = New_Vers_dll) ; если версии совпадают
                Goto, ContinueRead ; продолжить читать строки из списка баз

            ; Версии не совпадают, проверим их по частям (обходим некорректную инфу с сервера DrWeb'а)
            StringSplit, Exist_VersArray, Exist_Vers_dll, . ; делим версию на части
            StringSplit, New_VersArray, New_Vers_dll, .
            VersNotEqual = ; сбрасываем флаг
            Loop, %New_VersArray0%
            {
                If (Exist_VersArray%A_Index% != New_VersArray%A_Index%)
                    VersNotEqual := True ; ставим флаг, что версии не равны
            }
            If NOT VersNotEqual ; если после проверки СОВПАДАЮТ
                Goto, ContinueRead ; продолжить читать строки из списка баз
        }
    }

    ; База не требует проверки версии
    If FileExist(Arc_Name ".vdb") ; если база уже существует...
        Continue ; продолжить читать строки из загруженной страницы

    Add_To_Downloads: ; метка перехода для составления списка загрузки
    If NOT Downloads_List ; если список загрузки ещё пуст
        Downloads_List = %Arc_Name%.zip ; начинаем список
    Else
        Downloads_List = %Downloads_List%`n%Arc_Name%.zip ; добавляем архив в список, через перевод строки

    ContinueRead: ; метка перехода для продолжения чтения списка загрузки
    Continue ; продолжить читать строки из загруженной страницы
}
Sort, Downloads_List ; сортируем список, чтобы drwtoday шёл после остальных drw(N), и те его не перезаписывали

If NOT Base_Found ; если ни одной ссылки на базы не было найдено
{
    MsgBox,, Внимание!, ; показать сообщение
    ( LTrim
        В файле, полученном с FTP-сервера DrWeb:
        "%New_Base_List%"
        не удалось найти ссылки на антивирусные базы.
        Вероятно, изменилась структура этого файла.`n
        Обратитесь к разработчику скрипта :)
    )
    Goto, Del_Temp ; идём удалять временные файлы (конец скрипта)
}
If NOT Downloads_List ; если список обновлений пуст
{
    MsgBox,, Обновление не требуется!, ; показать сообщение
    ( LTrim
        Текущие версии локальных файлов - самые свежие :).
    )
    Goto, Del_Temp ; идём удалять временные файлы (конец скрипта)
}

/* ; ОТЛАДКА!!! СМОТРИМ СПИСОК ЗАГРУЗКИ (для отладки РАСкомментировать строчку, и её пару)
MsgBox, Будут загружены следующие архивы:`n%Downloads_List%
ExitApp ; конец скрипта
*/ ; ОТЛАДКА!!! СМОТРИМ СПИСОК ЗАГРУЗКИ (для отладки РАСкомментировать строчку, и её пару)

;=============================================================================================================
; СКОПИРОВАТЬ UNZIP.EXE ВО ВРЕМЕННУЮ ПАПКУ (КУДА БУДУТ ЗАГРУЖЕНЫ НОВЫЕ БАЗЫ)
FileInstall, UnZip.exe, %Downloads_Dir%\UnZip.exe, 1
If ErrorLevel
{
    MsgBox,, Внимание!, Неверно указан распаковщик. ; показать сообщение
    Goto, Del_Temp ; идём удалять временные файлы (конец скрипта)
}

;=============================================================================================================
; ОБРАБОТАТЬ СПИСОК ДЛЯ ЗАГРУЗКИ
Loop, Parse, Downloads_List, `n ; обработать составленный список для загрузки (разделитель - перевод строки)
{
    TrayTipText = Загружаю обновление: %A_LoopField% ; текст сообщения в трее
    SetTimer, RefreshTrayTip, 1000 ; обновлять сообщение каждую секунду
    Gosub, RefreshTrayTip ; показать сообщение в трее прямо сейчас

;~ /* ; ОТЛАДКА!!! НЕ ИДЁМ В ИНТЕРНЕТ (для отладки РАСкомментировать строчку, и её пару)
    ; ЗАГРУЗИТЬ НОВУЮ БАЗУ с FTP
    FileDelete, %FTPCommandFile% ; удалить предыдущий файл с командами для FTP
    FileAppend, ; пишем команды FTP в файл
    (LTrim Comments
        open %FTP_DrWeb% ; сервер DrWeb'а
        anonymous ; входить анонимно
        binary ; бинарный режим передачи
        get %FTP_Dir%/%A_LoopField% "%Downloads_Dir%\%A_LoopField%" ; что и куда качаем
        quit ; выход из FTP-режима
    ), %FTPCommandFile%
    RunWait, %comspec% /c "%FTP_Exe% -s:"%FTPCommandFile%" > "%FTPLogFile%"",, Hide

    ; АНАЛИЗ ЛОГА ЗАГРУЗКИ (УСПЕШНО ИЛИ НЕТ)
    Download_OK = ; сбросить указатель успешности загрузки
    Loop, read, %FTPLogFile% ; читаем лог загрузки
    {
        IfInString, A_LoopReadLine, File send OK ; если в строке указано, что "File send OK"
        {
            Download_OK := True ; флаг, что загрузка прошла успешно
            Break ; перестаём читать лог
        }
    }
;~ */ ; ОТЛАДКА!!! НЕ ИДЁМ В ИНТЕРНЕТ (для отладки РАСкомментировать строчку, её пару и 4 строки ниже)

/* ; ОТЛАДКА!!! ИМИТАЦИЯ ЗАГРУЗКИ (для отладки РАСкомментировать строчку, и её пару)
    Sleep, 1000 ; имитация загрузки :)
    Download_OK := True ; ОТЛАДКА!!!
    ; (проверка ошибок загрузки)
    If (A_LoopField = "dwntoday.zip") OR (A_LoopField = "drwtoday.zip")
        Download_OK =
*/ ; ОТЛАДКА!!! ИМИТАЦИЯ ЗАГРУЗКИ (для отладки РАСкомментировать строчку, и её пару)

    If NOT Download_OK ; если была ошибка загрузки
    {
        If NOT Log_Error ; если лог ошибок пуст
            Log_Error = %A_LoopField%
        Else
            Log_Error = %Log_Error%`n%A_LoopField%
        Continue ; пробуем скачать следующую базу
    }

    ; РАСПАКОВАТЬ ЗАГРУЖЕННУЮ БАЗУ
;~     UnPacker = %A_ProgramFiles%\WinRAR\WinRAR.exe ; использовать этот распаковщик
;~     RunWait, %UnPacker% e -O+ "%Downloads_Dir%\%A_LoopField%" "%A_WorkingDir%",, Hide ; WinRar

    RunWait, %Downloads_Dir%\UnZip.exe -o "%Downloads_Dir%\%A_LoopField%" -d "%A_WorkingDir%",, Hide
    ; параметры UnZip'а
    ; -o - перезаписывать имеющиеся файлы (параметр должен быть перед именем архива)
    ; имя распаковываемого архива
    ; -d - в какую папку распаковывать

    ; архив распакован, смотрим его содержимое чтобы записать в лог
    RunWait, %comspec% /c "%Downloads_Dir%\UnZip.exe -l "%Downloads_Dir%\%A_LoopField%" > "%ArcList%"",, Hide
    FileReadLine, ArcListLine, %ArcList%, 4 ; читаем 4-ю строку файла (первый файл в листинге)
    RegExMatch(ArcListLine, "\w+$", Ext) ; получаем расширение файла
    StringReplace, CurFile, A_LoopField, .zip, .%Ext% ; меняем расширение на соответствующее
    If NOT Log_Success ; если лог успешных операций пуст
        Log_Success = %CurFile%
    Else
        Log_Success = %Log_Success%`n%CurFile%

    ; УДАЛЯЕМ РАСПАКОВАННЫЙ АРХИВ
    If Del_Base ; если указано удалять архивы
        FileDelete, %A_LoopField% ; мочим архив
}

; Загрузки завершены, убираем сообщение в трее
SetTimer, RefreshTrayTip, Off
TrayTip ; удалить сообщение в трее
SoundPlay, %A_WinDir%\Media\ding.wav ; воспроизвести звук

;=============================================================================================================
; ПИШЕМ ЛОГ ОБНОВЛЕНИЙ
If Log_File ; если указано писать лог
{
    ; делаем так, чтобы последняя запись была наверху лога
    Tmp_Log = %Log_File%.tmp ; сначала будем писать во временный лог
    FileAppend,
    (LTrim Comments
        ======================================
        %A_DD%-%A_MMMM%-%A_YYYY%, %A_Hour%:%A_Min%:%A_Sec%
        --------------------------------------
    ), %Tmp_Log%

    If Log_Success ; если есть успешные операции
    {
        FileAppend,
        (LTrim Comments
            `nУстановлено обновление:
            %Log_Success%
        ), %Tmp_Log%
    }

    If Log_Error ; если есть ошибки закачки
    {
        FileAppend,
        (LTrim Comments
            `n`n!!!--- ВНИМАНИЕ ---!!!
            Эти файлы не удалось загрузить:
            %Log_Error%
        ), %Tmp_Log%
    }

    FileAppend,    `n======================================`n`n`n, %Tmp_Log%

    FileRead, Last_Log, %Log_File% ; читаем настоящий лог
    FileAppend,    %Last_Log%, %Tmp_Log% ; добавляем его ко временному
    FileMove, %Tmp_Log%, %Log_File%, 1 ; заменяем настоящий временным
}

If Log_Error ; если есть ошибки закачки
{
    IfExist, %Log_File% ; если лог существует
    {
        MsgBox, 20, Внимание!, Обновление завершено с ошибками.`nПоказать лог обновления ?
        IfMsgBox, Yes
        {
            Run, Notepad.exe "%Log_File%",,, Log_PID ; открываем лог в блокноте
            WinWait, ahk_pid %Log_PID% ; подождать окно лога
            WinActivate ; активизировать окно
        }
    }
    Else ; если лог не пишется
        MsgBox, 16, Внимание!, Обновление завершено с ошибками.
}
Else ; если ошибок не было
{
    IfExist, %Log_File% ; если лог существует
    {
        MsgBox, 260, Поздравляю!, Обновление успешно завершено.`nПоказать лог обновления ?
        IfMsgBox, Yes
        {
            Run, Notepad.exe "%Log_File%",,, Log_PID ; открываем лог в блокноте
            WinWait, ahk_pid %Log_PID% ; подождать окно лога
            WinActivate ; активизировать окно
        }
    }
    Else ; если лог не пишется
        MsgBox,, Поздравляю!, Обновление успешно завершено.
}

Del_Temp: ; удаление временных файлов
    Loop, Parse, Del_Temp_Files, | ; парсим список временных файлов
        FileDelete, %A_LoopField% ; удаляем временные файлы
ExitApp ; конец скрипта
;
; ============================================================================================================
RefreshTrayTip: ; подпрограмма обновления TrayTip'а
    TrayTip, Обновление..., %TrayTipText%
Return
; ============================================================================================================

; ============================================================================================================
FileExistInShell(Target_File) ; функция проверки возможности запуска файла
{
    ; В качестве параметра функция принимает имя файла (с расширением!)
    ; Если файл найден, то функция возвращает путь к нему.
    ; Обычно имеет смысл проверять исполнимые файлы, но это не обязательно :)

    ; Сначала ищем в App Paths
    Loop, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths, 2, 1 ; ищем путь в реестре
    {
        If (A_LoopRegName != Target_File) ; если текущий раздел не тот, что ищем
            Continue

        RegRead, Target_Path, %A_LoopRegKey%, %A_LoopRegSubKey%\%A_LoopRegName% ; читаем парам. "по умолчанию"
        IfExist, %Target_Path% ; если файл, указанный в реестре существует
            Return, %Target_Path% ; возвращаем путь к файлу
        Else ; если вдруг файл по указанному пути не существует
            Break ; больше в реестре не ищем
    }

    ; В App Paths не нашли, ищем в системных папках
    IfExist, %A_WinDir%\System32\%Target_File% ; если нашли файл
        Return, A_WinDir "\System32\" Target_File ; возвращаем путь к файлу

    IfExist, %A_WinDir%\%Target_File% ; если нашли файл
        Return, A_WinDir "\" Target_File ; возвращаем путь к файлу

    ; Напоследок ищем в переменной окружения Path
    EnvGet, EnvPath, Path ; получаем переменную окружения Path
    StringSplit, EnvPathArray, EnvPath, `; ; разбиваем на части в массив
    Loop, %EnvPathArray0% ; проверяем полученные пути
    {
        Target_Path := % EnvPathArray%A_Index% "\" Target_File ; составляем путь
        IfExist, %Target_Path% ; если нашли файл
            Return, %Target_Path% ; возвращаем путь к файлу
    }
    Return ; выходим из функции (не нашли файл)
} ; конец функции
; ============================================================================================================

Гы. Архив приложил, а сам код не запостил. Исправил.

Забрать скрипт со значком для компиляции.

Post's attachments

DrwUpdater.zip 8.15 kb, 1345 downloads since 2007-07-10 

You don't have the permssions to download the attachments of this post.
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).

2 (изменено: Androgen, 2007-07-10 17:59:21)

Re: AutoHotkey: обновлялка для DrWeb

UnZip, упакованный UPX'ом.

Post's attachments

UnZip.zip 45.32 kb, 1032 downloads since 2007-07-10 

You don't have the permssions to download the attachments of this post.
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).