最近项目涉及到注册表操作。列出主要api,已做备忘。本分大部分翻译自MSDN。
RegCreateKeyEx
新建指定注册表项,如果已经存在则打开。注册表项名称不区分大小写。
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
);
hKey [in]
主键,一般下面几项之一。
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
lpSubKey [in]
需要新建或打开的子键名称,如"SoftWare\\Microsoft"
Reserved
保留,只能是0.
lpClass [in, optional]
键的用户自定义类型,可以忽略,一般是NULL。
dwOptions [in]
该参数可以是以下值
REG_OPTION_BACKUP_RESTORE,0x00000004L
REG_OPTION_CREATE_LINK,0x00000002L
REG_OPTION_NON_VOLATILE,0x00000000L ,一般使用该值
REG_OPTION_VOLATILE,0x00000001L
samDesired [in]
定义访问权限
lpSecurityAttributes [in, optional]
定义返回的句柄是否可以被子进程继承,为NULL时不能继承。
phkResult [out]
保存返回的句柄
lpdwDisposition [out, optional]
可以是以下值。如果为空,则不返回。
REG_CREATED_NEW_KEY,0x00000001L 该键是新创建的键
REG_OPENED_EXISTING_KEY,0x00000002L 该键是已经存在的键
Return Values
成功则返回 ERROR_SUCCESS.
RegOpenKeyEx
打开指定注册表项
LONG WINAPI RegOpenKeyEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpSubKey,
_Reserved_ DWORD ulOptions,
_In_ REGSAM samDesired,
_Out_ PHKEY phkResult
);
参数用法与RegCreateKeyEx相同。
RegSetValueEx
设置注册表项的指定值。
LONG WINAPI RegSetValueEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName,
_Reserved_ DWORD Reserved,
_In_ DWORD dwType,
_In_ const BYTE *lpData,
_In_ DWORD cbData
);
hKey [in]
打开的注册表项句柄,注册表项必须包含KEY_SET_VALUE权限。
lpValueName [in, optional]
要设置的值的名字。如果没有,增加这个值。
Reserved
保留,只能是0.
dwType [in]
数据的类型,详细见http://msdn.microsoft.com/en-us/library/ms724884%28v=vs.85%29.aspx
lpData [in]
保存的值
cbData [in]
保存值的字节数。
Return Values
成功则返回 ERROR_SUCCESS.
RegQueryValueEx
查询指定value的data和type
LONG WINAPI RegQueryValueEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName,
_Reserved_ LPDWORD lpReserved,
_Out_opt_ LPDWORD lpType,
_Out_opt_ LPBYTE lpData,
_Inout_opt_ LPDWORD lpcbData
);
参数用法同RegSetValueEx
RegEnumKeyEx
列举指定键值的子键。
LONG WINAPI RegEnumKeyEx(
_In_ HKEY hKey,
_In_ DWORD dwIndex,
_Out_ LPTSTR lpName,
_Inout_ LPDWORD lpcName,
_Reserved_ LPDWORD lpReserved,
_Inout_ LPTSTR lpClass,
_Inout_opt_ LPDWORD lpcClass,
_Out_opt_ PFILETIME lpftLastWriteTime
);
hKey [in]
打开的价值句柄,打开时必须带有KEY_ENUMERATE_SUB_KEYS权限。
dwIndex [in]
要检索的子键序号
lpName [out]
接收子键名称的buffer
lpcName [in, out]
lpName 的长度。
Reserved
保留,只能是0.
lpClass [in, out]
buffer的指针,接收用户自定义的类型。
lpcClass [in, out, optional]
lpClass 的长度。
lpftLastWriteTime [out, optional]
最后修改的时间
Return value
成功返回ERROR_SUCCESS。
没有更多的子键返回ERROR_NO_MORE_ITEMS
lpName buffer太小,不能写入键值名。返回ERROR_MORE_DATA
RegCloseKey
关闭打开的句柄
LONG WINAPI RegCloseKey(
_In_ HKEY hKey
);
hKey [in]
要关闭的句柄。
Return Values
成功则返回 ERROR_SUCCESS.
附加两个例子,摘自MSDN。
// QueryKey - Enumerates the subkeys of key and its associated values.
// hKey - Key whose subkeys and values are to be enumerated.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
void QueryKey(HKEY hKey)
{
TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time
DWORD i, retCode;
TCHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
// Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// Enumerate the subkeys, until RegEnumKeyEx fails.
if (cSubKeys)
{
printf( "\nNumber of subkeys: %d\n", cSubKeys);
for (i=0; i<cSubKeys; i++)
{
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i,
achKey,
&cbName,
NULL,
NULL,
NULL,
&ftLastWriteTime);
if (retCode == ERROR_SUCCESS)
{
_tprintf(TEXT("(%d) %s\n"), i+1, achKey);
}
}
}
// Enumerate the key values.
if (cValues)
{
printf( "\nNumber of values: %d\n", cValues);
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS )
{
_tprintf(TEXT("(%d) %s\n"), i+1, achValue);
}
}
}
}
void __cdecl _tmain(void)
{
HKEY hTestKey;
if( RegOpenKeyEx( HKEY_CURRENT_USER,
TEXT("SOFTWARE\\Microsoft"),
0,
KEY_READ,
&hTestKey) == ERROR_SUCCESS
)
{
QueryKey(hTestKey);
}
RegCloseKey(hTestKey);
}
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
//*************************************************************
//
// RegDelnodeRecurse()
//
// Purpose: Deletes a registry key and all its subkeys / values.
//
// Parameters: hKeyRoot - Root key
// lpSubKey - SubKey to delete
//
// Return: TRUE if successful.
// FALSE if an error occurs.
//
//*************************************************************
BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey)
{
LPTSTR lpEnd;
LONG lResult;
DWORD dwSize;
TCHAR szName[MAX_PATH];
HKEY hKey;
FILETIME ftWrite;
// First, see if we can delete the key without having
// to recurse.
lResult = RegDeleteKey(hKeyRoot, lpSubKey);
if (lResult == ERROR_SUCCESS)
return TRUE;
lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS)
{
if (lResult == ERROR_FILE_NOT_FOUND) {
printf("Key not found.\n");
return TRUE;
}
else {
printf("Error opening key.\n");
return FALSE;
}
}
// Check for an ending slash and add one if it is missing.
lpEnd = lpSubKey + lstrlen(lpSubKey);
if (*(lpEnd - 1) != TEXT('\\'))
{
*lpEnd = TEXT('\\');
lpEnd++;
*lpEnd = TEXT('\0');
}
// Enumerate the keys
dwSize = MAX_PATH;
lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
NULL, NULL, &ftWrite);
if (lResult == ERROR_SUCCESS)
{
do {
StringCchCopy (lpEnd, MAX_PATH*2, szName);
if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
break;
}
dwSize = MAX_PATH;
lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
NULL, NULL, &ftWrite);
} while (lResult == ERROR_SUCCESS);
}
lpEnd--;
*lpEnd = TEXT('\0');
RegCloseKey (hKey);
// Try again to delete the key.
lResult = RegDeleteKey(hKeyRoot, lpSubKey);
if (lResult == ERROR_SUCCESS)
return TRUE;
return FALSE;
}
//*************************************************************
//
// RegDelnode()
//
// Purpose: Deletes a registry key and all its subkeys / values.
//
// Parameters: hKeyRoot - Root key
// lpSubKey - SubKey to delete
//
// Return: TRUE if successful.
// FALSE if an error occurs.
//
//*************************************************************
BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey)
{
TCHAR szDelKey[MAX_PATH*2];
StringCchCopy (szDelKey, MAX_PATH*2, lpSubKey);
return RegDelnodeRecurse(hKeyRoot, szDelKey);
}
void __cdecl main()
{
BOOL bSuccess;
bSuccess = RegDelnode(HKEY_CURRENT_USER, TEXT("Software\\TestDir"));
if(bSuccess)
printf("Success!\n");
else printf("Failure.\n");
}