Делал недавно одну утилитку в которой нужно было управлять конкретными значениями в конкретных ключах реестра.
Что бы не ковыряться каждый раз с низкоуровневыми вызовами сделал высокоуровневую обертку.
Может кому пригодится.
Файл ssReg.pbi
Global ssRegIsError=#False
Global ssRegErrorCode.l
Global ssRegErrorText.s
Procedure.s ssRegGetErrorText(ErrCode)
Define result.s=""
Protected *Memory = AllocateMemory (255)
Protected length = FormatMessage_ (#FORMAT_MESSAGE_FROM_SYSTEM, #Null, ErrCode, 0, *Memory, 255, #Null)
result=PeekS (*Memory, length - 2)
FreeMemory (*Memory)
ProcedureReturn result
EndProcedure
Procedure ssRegCheckRoot(Root$) ;проверяет и возвращает числовое значение корня
Protected RegBranch
If Root$="HKEY_CURRENT_USER"
RegBranch=#HKEY_CURRENT_USER
ElseIf Root$="HKEY_LOCAL_MACHINE"
RegBranch=#HKEY_LOCAL_MACHINE
Else
ssRegIsError=#True
ssRegErrorCode=0
ssRegErrorText="Недопустимый корень ключа реестра - можно только HKEY_CURRENT_USER или HKEY_LOCAL_MACHINE"
ProcedureReturn #False
EndIf
ProcedureReturn RegBranch
EndProcedure
Procedure ssRegCheckType(VType$) ;проверяет и возвращает числовое значение типа
Protected nVType
ssRegIsError=#False
If VType$="REG_SZ"
nVType=#REG_SZ
ElseIf VType$="REG_DWORD"
nVType=#REG_DWORD
Else
ssRegIsError=#True
ssRegErrorCode=0
ssRegErrorText="Недопустимый тип значени - можно только REG_SZ или REG_DWORD"
ProcedureReturn #False
EndIf
ProcedureReturn nVType
EndProcedure
Procedure ssRegCreateKey(Key$)
Protected RegBranch, pos=FindString(Key$,"\")
Protected Root$=Left(Key$,pos-1), subKey$=Mid(Key$,pos+1)
ssRegIsError=#False
RegBranch=ssRegCheckRoot(Root$)
If RegBranch=#False Or ssRegIsError
ProcedureReturn #False
EndIf
; LONG WINAPI RegCreateKeyEx(
; _In_ HKEY hKey,
; _In_ LPCTSTR lpSubKey,
; _Reserved_ DWORD Reserved,
; _In_opt_ LPTSTR lpClass,
; _In_ DWORD dwOptions,
; _In_ REGSAM samDesired,
; _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
; _Out_ PHKEY phkResult,
; _Out_opt_ LPDWORD lpdwDisposition
; );
Protected hKey
Protected OperType ;see below
;REG_CREATED_NEW_KEY(0x00000001L) The key did not exist and was created.
;REG_OPENED_EXISTING_KEY(0x00000002L) The key existed and was simply opened without being changed.
Protected res=RegCreateKeyEx_(RegBranch, subKey$, 0, #Null, 0, #KEY_ALL_ACCESS, #Null, @hKey, @OperType)
If res=#ERROR_SUCCESS
RegCloseKey_(hKey)
ProcedureReturn OperType
Else
ssRegIsError=#True
ssRegErrorCode = res
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
EndProcedure
Procedure ssRegDeleteKey(Key$)
Protected RegBranch, pos=FindString(Key$,"\")
Protected Root$=Left(Key$,pos-1), subKey$=Mid(Key$,pos+1)
ssRegIsError=#False
RegBranch=ssRegCheckRoot(Root$)
If RegBranch=#False Or ssRegIsError
ProcedureReturn #False
EndIf
; LONG WINAPI RegDeleteKeyEx(
; _In_ HKEY hKey,
; _In_ LPCTSTR lpSubKey,
; _In_ REGSAM samDesired,
; _Reserved_ DWORD Reserved
; );
; LONG WINAPI RegDeleteTree(
; _In_ HKEY hKey,
; _In_opt_ LPCTSTR lpSubKey
; );
;Protected res=RegDeleteTree_(RegBranch,subKey$)
; LSTATUS SHDeleteKey(
; _In_ HKEY hkey,
; _In_opt_ LPCTSTR pszSubKey
; );
Protected res=SHDeleteKey_(RegBranch,subKey$)
If res=#ERROR_SUCCESS
ProcedureReturn #True
Else
ssRegIsError=#True
ssRegErrorCode = GetLastError_()
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
EndProcedure
Procedure ssRegKeyExist(Key$)
Protected RegBranch, pos=FindString(Key$,"\")
Protected Root$=Left(Key$,pos-1), subKey$=Mid(Key$,pos+1)
ssRegIsError=#False
RegBranch=ssRegCheckRoot(Root$)
If RegBranch=#False Or ssRegIsError
ProcedureReturn #False
EndIf
;result = RegOpenKeyEx_ (RegBranch , subkey$, 0, flags, @gKeyHandle)
Protected hKey
Protected result = RegOpenKeyEx_ (RegBranch , subkey$, 0, #KEY_ALL_ACCESS, @hKey)
If result = #ERROR_SUCCESS
RegCloseKey_(hKey)
ProcedureReturn #True
Else
ssRegIsError=#True
ssRegErrorCode = GetLastError_()
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
EndProcedure
Procedure ssRegSetValue(Key$, VName$, VType$, VData$)
Protected RegBranch, pos=FindString(Key$,"\")
Protected Root$=Left(Key$,pos-1), subKey$=Mid(Key$,pos+1)
ssRegIsError=#False
RegBranch=ssRegCheckRoot(Root$)
If RegBranch=#False Or ssRegIsError
ProcedureReturn #False
EndIf
; проверить тип значения
Protected nVType=ssRegCheckType(VType$)
If nVType=#False Or ssRegIsError
ProcedureReturn #False
EndIf
;
If nVType=#REG_SZ ;удвоить \ => \\
; Protected Tmp$="" ;PeekS(*VData), VData$=""
; ;n=CountString(Tmp$, "\")
; n=CountString(VData$, "\")
; If n>0
; For i=1 To n
; Tmp$+StringField(VData$, i, "\")+"\\"
; Next
; Tmp$+StringField(VData$, n+1, "\")
; EndIf
ElseIf nVType=#REG_DWORD
Protected nVData.l=Val(VData$)
EndIf
;
Protected hKey
Protected res = RegOpenKeyEx_ (RegBranch , subkey$, 0, #KEY_ALL_ACCESS, @hKey)
If res = #ERROR_SUCCESS
; LONG WINAPI RegSetValueEx(
; _In_ HKEY hKey,
; _In_opt_ LPCTSTR lpValueName,
; _Reserved_ DWORD Reserved,
; _In_ DWORD dwType,
; _In_ const BYTE *lpData,
; _In_ DWORD cbData
; );
If nVType=#REG_SZ
;res=RegSetValueEx_(hKey, VName$, 0, nVType, @Tmp$, Len(Tmp$)+1)
res=RegSetValueEx_(hKey, VName$, 0, nVType, @VData$, Len(VData$)+1)
ElseIf nVType=#REG_DWORD
res=RegSetValueEx_(hKey, VName$, 0, nVType, @nVData, 4)
EndIf
RegCloseKey_(hKey)
If res = #ERROR_SUCCESS
ProcedureReturn #True
Else
ssRegIsError=#True
ssRegErrorCode = res
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
Else
ssRegIsError=#True
ssRegErrorCode = res
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
EndProcedure
Procedure ssRegGetValue(Key$, VName$, *VType.String, *VData.String)
Protected RegBranch, pos=FindString(Key$,"\")
Protected Root$=Left(Key$,pos-1), subKey$=Mid(Key$,pos+1)
ssRegIsError=#False
RegBranch=ssRegCheckRoot(Root$)
If RegBranch=#False Or ssRegIsError
ProcedureReturn #False
EndIf
Protected hKey
Protected res = RegOpenKeyEx_ (RegBranch , subKey$, 0, #KEY_ALL_ACCESS, @hKey)
If res <> #ERROR_SUCCESS ;ошибка при открытии ключа
ssRegIsError=#True
ssRegErrorCode = GetLastError_()
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
Else
Protected lpType.l
Protected lpcbData = 255
Protected lpData.s=Space(lpcbData)
res = RegQueryValueEx_(hKey, VName$, 0, @lType, @lpData, @lpcbData)
RegCloseKey_(hKey)
If res=#ERROR_SUCCESS
If lType=#REG_SZ
*VType\s="REG_SZ"
*VData\s=PeekS(@lpData)
ElseIf lType=#REG_DWORD
*VType\s="REG_DWORD"
*VData\s=Str(PeekL(@lpData))
Else
ssRegIsError=#True
ssRegErrorCode = 0
ssRegErrorText="Недопустимый тип значения"
ProcedureReturn #False
EndIf
ProcedureReturn #True
Else
ssRegIsError=#True
ssRegErrorCode = res
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
EndIf
EndProcedure
Procedure ssRegDeleteValue(Key$, VName$)
Protected RegBranch, pos=FindString(Key$,"\")
Protected Root$=Left(Key$,pos-1), subKey$=Mid(Key$,pos+1)
ssRegIsError=#False
RegBranch=ssRegCheckRoot(Root$)
If RegBranch=#False Or ssRegIsError
ProcedureReturn #False
EndIf
Protected hKey
Protected res = RegOpenKeyEx_ (RegBranch , subKey$, 0, #KEY_ALL_ACCESS, @hKey)
If res <> #ERROR_SUCCESS ;ошибка при открытии ключа
ssRegIsError=#True
ssRegErrorCode = GetLastError_()
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
Else
; LSTATUS SHDeleteValue(
; HKEY hkey,
; LPCTSTR pszSubKey,
; LPCTSTR pszValue
; );
;res = SHDeleteValue_(hKey, subKey$, VName$)
; LONG WINAPI RegDeleteValue(
; _In_ HKEY hKey,
; _In_opt_ LPCTSTR lpValueName
; );
;
res = RegDeleteValue_(hKey, VName$)
RegCloseKey_(hKey)
If res=#ERROR_SUCCESS
ProcedureReturn #True
Else
ssRegIsError=#True
ssRegErrorCode = res
ssRegErrorText=ssRegGetErrorText(ssRegErrorCode)
ProcedureReturn #False
EndIf
EndIf
EndProcedureпользовательские функции
ssRegKeyExist(Key$)
ssRegCreateKey(Key$)
ssRegDeleteKey(Key$)
ssRegSetValue(Key$, VName$, VType$, VData$)
ssRegGetValue(Key$, VName$, *VType.String, *VData.String)
ssRegDeleteValue(Key$, VName$)
остальные - внутренние.
Функции возвращают логическое значение.
При возвращенном значении #False еще устанавливаются глобальные переменные
ssRegIsError=#True
ssRegErrorCode - код ошибки
ssRegErrorText - текст описания ошибки
Если значения не существует то ssRegGetValue()=#False и ssRegErrorCode =2
Ограничения.
Тип значения только "REG_SZ" и "REG_DWORD". Задаются именно такой текстовой строкой.
Ветви реестра только "HKEY_CURRENT_USER" и "HKEY_LOCAL_MACHINE". Задаются именно такой текстовой строкой.
В ssRegSetValue() данные передаются строкой - даже число типа "REG_DWORD"
пример:
Key$="HKEY_CURRENT_USER\Software\Diasoft\MICalculator\UserSettings" VNAME$="Активный скин" VTYPE$="REG_SZ" VDATA$="CzInsCorp" if ssRegSetValue(Key$, VName$, VType$, VData$) ... else ... endif VNAME$="Number" VTYPE$="REG_DWORD" VDATA$=str(456) if ssRegSetValue(Key$, VName$, VType$, VData$) ... else ... endif
Этим набором функций нельзя исследовать реестр т.к. нет функций перебора т.к. не стояла такая задача.