1

Тема: AutoHotkey: пара функций, облегчающих работу с реестром

Если вы захотите узнать, существует ли некий параметр (Value) в реестре, то можно, используя команду RegRead, смотреть, что в ErrorLevel. Если ErrorLevel = 0, значит, параметр существует. Однако, если вы захотите проверить существование раздела (Key), то столь же простого средства в AutoHotkey нет. В этом случае ErrorLevel будет равен 0 , только если есть какое-либо значение у параметра "по умолчанию", находящегося в проверяемом разделе.
Кроме того, я вообще нахожу неудобным синтаксис команды RegRead. Это особенно ощущается, когда читаемый раздел или параметр пишется не в теле скрипта, а получается динамически (например, при анализе, скажем, reg-файла).

Вот, для облегчения работы с реестром, я написал пару функций. Первая - проверяет существование раздела, вторая - существование параметра. Результат - как обычно, в ErrorLevel. Вдобавок, вторая функция возвращает значение параметра (если оно понадобится). И в вызове обеих функций используется привычный вид разделов/параметров реестра. Повторяю, что это удобно при динамическом (в процессе выполнения скрипта) получении разделов/параметров.
Функции, как обычно, можно просто вставить в ваш скрипт, или подключать их к любым скриптам директивой #Include.

;*******************************************************************************
; AutoHotkey Version:   1.0.44.09+
; Автор:                Androgen Belkin
; Имя скрипта:          RegKey(Value)Exist().ahk (v.1.0)
;*******************************************************************************
; Функции проверки существования раздела или существования параметра
; (если параметр существует, то возвращается его значение).
; Тестировалось на WinXP SP2.
;*******************************************************************************
; =============================================================================================================
RegKeyExist( InputKey ) ; функция проверки существования раздела
{
    IfNotInString, InputKey, \ ; если в строке НЕТ бэкслэша (зачем-то проверяют существование корневого раздела), то...
    {
        Loop, %InputKey%,, 1 ; проверяем наличие в корневом разделе каких-либо подразделов
        {
            If A_LoopRegKey ; если хоть один подраздел найден, то...
            {
                ErrorLevel = 0 ; выставляем указатель, что раздел найден
                Return ; выйти из функции
            }
        }
        ; если подразделов не оказалось, то...
        ErrorLevel = 1 ; выставляем указатель, что раздел НЕ найден
        Return ; выйти из функции
    }
    ; Если в строке есть бэкслэш, то продолжаем...
    StringLeft, RootKey, InputKey, InStr( InputKey, "\" ) - 1 ; получить из строки RootKey
    StringTrimLeft, SubKey, InputKey, InStr( InputKey, "\" ) ; получить остальную часть строки
    StringRight, KeyName, SubKey, StrLen( SubKey ) - InStr( SubKey, "\", False, 0 ) ; берем последнюю часть строки (имя раздела)
    StringTrimRight, ParentKey, SubKey, StrLen( KeyName ) + 1 ; отрезать имя раздела (получаем родительский раздел)
    Loop, %RootKey%, %ParentKey%, 1 ; Loop-атим родительский раздел
    {
        If ( A_LoopRegName = KeyName AND A_LoopRegType = "Key" ) ; если имя найдено и это - раздел реестра, то...
        {
            ErrorLevel = 0 ; выставляем указатель, что раздел найден
            Return ; выйти из функции
        }
        Else ; если имя пока не найдено, то...
            Continue ; продолжаем цикл
    }
    ; если проверяемый раздел так и не найден, то...
    ErrorLevel = 1 ; выставляем указатель, что раздел НЕ найден
    Return ; выйти из функции
} ; конец функции
; =============================================================================================================

; =============================================================================================================
RegValueExist( InputValue ) ; функция проверки существования параметра (если параметр существует, то возвращается его значение)
{
    IfNotInString, InputValue, \ ; если в строке НЕТ бэкслэша (зачем-то проверяют существование корневого раздела), то...
    {
        ErrorLevel = 1 ; выставляем указатель, что параметр НЕ найден
        Return ; выйти из функции
    }
    ; Если в строке есть бэкслэш, то продолжаем...
    StringLeft, RootKey, InputValue, InStr( InputValue, "\" ) - 1 ; получить из строки RootKey
    StringTrimLeft, SubKey, InputValue, InStr( InputValue, "\" ) ; получить остальную часть строки
    StringRight, ValueName, SubKey, StrLen( SubKey ) - InStr( SubKey, "\", False, 0 ) ; берем последнюю часть строки (имя параметра)
    StringTrimRight, ParentKey, SubKey, StrLen( ValueName ) + 1 ; отрезать имя параметра (получаем родительский раздел)
    RegRead, Value, %RootKey%, %ParentKey%, %ValueName% ; читаем значение параметра
    Return, Value ; выносим из функции значение параметра (ErrorLevel выставляется автоматически)
} ; конец функции
; =============================================================================================================

ПРИМЕРЫ ВЫЗОВОВ ФУНКЦИЙ

Проверка существования раздела:

; Способ, на мой взгляд, самый используемый (читаем переменную CheckKey из, например, ini-файла):
CheckKey = HKLM\SOFTWARE\AutoHotkey ; назначаем проверяемый раздел
RegKeyExist( CheckKey ) ; вызываем функцию проверки существования раздела
If ErrorLevel
    MsgBox, Раздел не существует!
Else
    MsgBox, Раздел существует.
Return
; ---------------------
; Или так (назначаем проверку прямо в теле скрипта):
RegKeyExist( "HKLM\SOFTWARE\AutoHotkey" ) ; вызываем функцию проверки существования раздела
If ErrorLevel
    MsgBox, Раздел не существует!
Else
    MsgBox, Раздел существует.
Return
; ---------------------
; Или вот так (используем уже заданные ранее переменные):
RootKey = HKLM
SubKey = SOFTWARE\AutoHotkey
RegKeyExist( RootKey "\" SubKey ) ; вызываем функцию проверки существования раздела
If ErrorLevel
    MsgBox, Раздел не существует!
Else
    MsgBox, Раздел существует.
Return

Проверка существования параметра:

; Способ, на мой взгляд, самый используемый (читаем переменную CheckValue из, например, ini-файла):
CheckValue = HKEY_CLASSES_ROOT\.ahk\ ; проверить существование параметра "по умолчанию" (после последнего бэкслэша ничего не указано)
RegValueExist( CheckValue ) ; вызываем функцию проверки существования параметра
If ErrorLevel
    MsgBox, Параметр не существует!
Else
    MsgBox, Параметр существует.
Return
; ---------------------
; Способ, на мой взгляд, самый используемый (читаем переменную CheckValue из, например, ini-файла):
CheckValue = HKEY_CLASSES_ROOT\.ahk\ ; проверить существование параметра "по умолчанию" (после последнего бэкслэша ничего не указано)
Value := RegValueExist( CheckValue ) ; вызываем функцию проверки существования параметра и получаем значение параметра
If ErrorLevel
    MsgBox, Параметр не существует!
Else
    MsgBox, Параметр существует.`nValue = %Value%
Return
; ---------------------
; Или так (назначаем проверку прямо в теле скрипта):
Value := RegValueExist( "HKLM\SOFTWARE\AutoHotkey\InstallDir" ) ; получаем значение параметра "InstallDir"
If ErrorLevel
    MsgBox, Параметр не существует!
Else
    MsgBox, Параметр существует.`nValue = %Value%
Return
; ---------------------
; Или вот так (используем уже заданные ранее переменные):
RootKey = HKLM
SubKey = SOFTWARE\AutoHotkey
ValueName = InstallDir
Value := RegValueExist( RootKey "\" SubKey "\" ValueName ) ; получаем значение параметра "InstallDir"
If ErrorLevel
    MsgBox, Параметр не существует!
Else
    MsgBox, Параметр существует.`nValue = %Value%
Return

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

Post's attachments

RegKey(Value)Exist().zip 2.16 kb, 672 downloads since 2006-08-23 

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

2

Re: AutoHotkey: пара функций, облегчающих работу с реестром

Небольшое добавление. Касается оно параметра "по умолчанию" (Default). Тут такая тонкость. С одной стороны этот параметр всегда существует, и его всегда можно видеть в редакторе реестра, даже если у него нет никакого значения. Он настолько "существует", что даже не получится удалить этот параметр. С другой стороны, (как я где-то прочел) этот параметр считается несуществующим пока у него нет никакого значения. Т.е. если значение этого параметра не задано, то о самом параметре нет никаких данных в физических файлах реестра.
Поэтому функция проверки существования параметра возвращает ErrorLevel = 1, если у этого параметра не задано никакого значения. Но если вы хотите считать, что этот параметр существует всегда (как это можно видеть в regedit'е), то к указанной функции нужно просто добавить пару строчек. Вот так:

; ============================================================================================================
RegValueExist( InputValue ) ; функция проверки существования параметра (если параметр существует, то возвращается его значение)
{
    IfNotInString, InputValue, \ ; если в строке НЕТ бэкслэша (зачем-то проверяют существование корневого раздела), то...
    {
        ErrorLevel = 1 ; выставляем указатель, что параметр НЕ найден
        Return ; выйти из функции
    }
    ; Если в строке есть бэкслэш, то продолжаем...
    StringLeft, RootKey, InputValue, InStr( InputValue, "\" ) - 1 ; получить из строки RootKey
    StringTrimLeft, SubKey, InputValue, InStr( InputValue, "\" ) ; получить остальную часть строки
    StringRight, ValueName, SubKey, StrLen( SubKey ) - InStr( SubKey, "\", False, 0 ) ; берем последнюю часть строки (имя параметра)
    StringTrimRight, ParentKey, SubKey, StrLen( ValueName ) + 1 ; отрезать имя параметра (получаем родительский раздел)
    RegRead, Value, %RootKey%, %ParentKey%, %ValueName% ; читаем значение параметра
    If ValueName = ; если имя параметра - "по умолчанию", то...
        ErrorLevel = 0 ; будем считать, что параметр "по умолчанию" существует всегда (независимо от того есть у него значение или нет)         
    Return, Value ; выносим из функции значение параметра (ErrorLevel выставляется автоматически)
} ; конец функции
; ============================================================================================================
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).