首页 > 编程语言 >Win32编程之注册表的相关操作(十四)

Win32编程之注册表的相关操作(十四)

时间:2023-09-20 15:11:55浏览次数:64  
标签:HKEY 函数 hKey 编程 指定 Win32 句柄 注册表

一、设置注册表项的值

RegOpenKeyEx函数

RegOpenKeyEx 函数是 Windows API 中的一个函数,用于打开注册表中的一个指定注册表项的句柄。通过该句柄,您可以读取或修改该注册表项中的值和子项。

函数原型:

LONG RegOpenKeyEx(
  HKEY   hKey,         // 指定基本注册表项的句柄
  LPCTSTR lpSubKey,    // 指定要打开的注册表子项的名称
  DWORD  ulOptions,    // 保留参数,通常为 0
  REGSAM samDesired,   // 指定对注册表项的访问权限
  PHKEY  phkResult     // 接收打开的注册表项的句柄
);

参数解释:

  • hKey:指定一个基本注册表项的句柄,它是一个 HKEY 类型的句柄,用于指定在哪个根注册表项下打开子项。常用的根注册表项包括 HKEY_LOCAL_MACHINEHKEY_CURRENT_USER 等。
  • lpSubKey:指定要打开的注册表子项的名称。这是一个以 null 结尾的字符串。
  • ulOptions:保留参数,通常为 0。
  • samDesired:指定对注册表项的访问权限,通常使用 KEY_READ 或 KEY_WRITE。您可以使用不同的访问权限标志来控制读取、写入和修改注册表的权限。
  • phkResult:指向 HKEY 类型的指针,用于接收打开的注册表项的句柄。

返回值:

  • 如果函数调用成功,返回 ERROR_SUCCESS(0),并且 phkResult 包含打开的注册表项的句柄。
  • 如果函数调用失败,返回一个非零的错误代码,可以使用 FormatMessage 函数来获取错误信息。

函数功能:

RegOpenKeyEx 函数用于打开指定注册表项的句柄,以便对其进行读取或修改操作,通过该句柄,可以执行以下操作:

  • 使用 RegQueryValueEx 函数来读取注册表项的值。
  • 使用 RegSetValueEx 函数来设置注册表项的值。
  • 使用 RegDeleteValue 函数来删除注册表项的值。
  • 使用 RegEnumKeyEx 函数来列举子项。

RegSetValueEx函数 

RegSetValueEx 函数用于设置或创建注册表中指定键的值。通过该函数,您可以将不同类型的数据(如字符串、二进制数据、整数值等)写入到注册表中。

函数原型:

LONG RegSetValueEx(
  HKEY       hKey,         // 指定一个打开的注册表项的句柄
  LPCTSTR    lpValueName,  // 指定要设置的值的名称
  DWORD      Reserved,     // 保留参数,通常为 0
  DWORD      dwType,       // 指定值的类型,如 REG_SZ、REG_DWORD 等
  const BYTE *lpData,      // 指向数据的指针
  DWORD      cbData        // 指定数据的大小(字节数)
);

参数解释:

  • hKey:指定一个打开的注册表项的句柄,您可以使用 RegOpenKeyEx 函数来打开注册表项。
  • lpValueName:指定要设置的值的名称,它是一个以 null 结尾的字符串。
  • Reserved:保留参数,通常为 0。
  • dwType:指定要设置的值的类型,例如 REG_SZ 表示字符串类型、REG_DWORD 表示双字(DWORD)类型等。不同的类型需要使用不同的数据类型和数据格式。
  • lpData:指向要写入注册表的数据的指针,数据的格式和类型必须与 dwType 参数匹配。
  • cbData:指定数据的大小(字节数),即 lpData 缓冲区中要写入的数据的字节数。

返回值:

  • 如果函数调用成功,返回 ERROR_SUCCESS(0)。
  • 如果函数调用失败,返回一个非零的错误代码,可以使用 FormatMessage 函数来获取错误信息。

函数功能:

RegSetValueEx 函数用于设置或创建注册表中的一个特定键的值。它允许您将不同类型的数据写入到注册表中,并指定值的类型(dwType)以及数据(lpData)的格式。如果指定的键和值名称不存在,它还可以创建它们。

示例代码:

#include <Windows.h>
#include <stdio.h>

int main() {
    HKEY hKey;

    // 打开或创建注册表项 HKEY_CURRENT_USER\Software\MyApp
    LONG result = RegCreateKeyEx(
        HKEY_CURRENT_USER,
        TEXT("Software\\MyApp"),
        0,
        NULL,
        REG_OPTION_NON_VOLATILE,  // 表示注册表项将在系统重启后保留
        KEY_WRITE,
        NULL,
        &hKey,
        NULL
    );

    if (result == ERROR_SUCCESS) {
        const WCHAR* valueName = TEXT("MyValue");
        const char* valueData = "Hello, Registry!";

        // 设置字符串值
        result = RegSetValueEx(
            hKey,
            valueName,
            0,
            REG_SZ,
            (BYTE*)valueData,
            strlen(valueData) + 1  // 包括 null 终止符的大小
        );

        if (result == ERROR_SUCCESS) {
            printf("Registry value set successfully.\n");
        }
        else {
            printf("Failed to set registry value.\n");
        }

        // 关闭注册表项句柄
        RegCloseKey(hKey);
    }
    else {
        printf("Failed to open or create registry key.\n");
    }

    return 0;
}

二、读取注册表项的值

RegQueryValueEx函数

RegQueryValueEx 函数用于读取注册表中指定键的值。通过该函数,您可以检索注册表项中的字符串、二进制数据、整数值等不同类型的数据

函数原型:

LONG RegQueryValueEx(
  HKEY    hKey,           // 指定一个打开的注册表项的句柄
  LPCTSTR lpValueName,    // 指定要检索的值的名称
  LPDWORD lpReserved,     // 保留参数,通常为 NULL
  LPDWORD lpType,         // 用于接收值的类型
  LPBYTE  lpData,         // 用于接收值数据的缓冲区
  LPDWORD lpcbData        // 指定缓冲区大小,接收数据的字节数
);

参数解释:

  • hKey:指定一个打开的注册表项的句柄,您可以使用 RegOpenKeyEx 函数来打开注册表项。
  • lpValueName:指定要检索的值的名称,它是一个以 null 结尾的字符串。
  • lpReserved:保留参数,通常为 NULL
  • lpType:一个指向 DWORD 类型的变量的指针,用于接收值的类型,例如 REG_SZREG_DWORD 等。
  • lpData:一个指向缓冲区的指针,用于接收检索到的值的数据。
  • lpcbData:一个指向 DWORD 类型的变量的指针,用于指定 lpData 缓冲区的大小,以接收检索到的数据的字节数。

返回值:

  • 如果函数调用成功,返回 ERROR_SUCCESS(0),并且 lpData 缓冲区中包含检索到的数据。
  • 如果函数调用失败,返回一个非零的错误代码,可以使用 FormatMessage 函数来获取错误信息。

函数功能:

RegQueryValueEx 函数用于从指定的注册表项中读取一个特定值的数据。它根据提供的注册表键和值的名称,将相应的数据检索到 lpData 缓冲区中,并通过 lpType 指针返回数据的类型。此函数可以用于读取字符串、二进制数据、整数等不同类型的值。

示例代码:

#include <Windows.h>
#include <stdio.h>

int main() {
    HKEY hKey;
    DWORD dwType;
    DWORD dwSize = MAX_PATH;
    char value[MAX_PATH];

    // 打开注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
    LONG result = RegOpenKeyEx(
        HKEY_CURRENT_USER,
        TEXT("Software\\MyApp"),
        0,
        KEY_READ,
        &hKey
    );

    if (result == ERROR_SUCCESS) {
        // 读取注册表项的 "MyValue" 值
        result = RegQueryValueEx(
            hKey,
            TEXT("MyValue"),
            NULL,
            &dwType,
            (LPBYTE)value,
            &dwSize
        );

        if (result == ERROR_SUCCESS && dwType == REG_SZ) {
            printf("Program Files Directory: %s\n", value);
        }
        else {
            printf("Failed to read registry value.\n");
        }

        // 关闭注册表项句柄
        RegCloseKey(hKey);
    }
    else {
        printf("Failed to open registry key.\n");
    }

    return 0;
}

三、删除注册表项的值

RegDeleteValue函数

RegDeleteValue 函数用于删除注册表中指定键的特定值。通过该函数,您可以删除注册表中的一个值,以清除不再需要的注册表数据  

函数原型:

LONG RegDeleteValue(
  HKEY    hKey,         // 指定一个打开的注册表项的句柄
  LPCTSTR lpValueName   // 指定要删除的值的名称
);

参数解释:

  • hKey:指定一个打开的注册表项的句柄,您可以使用 RegOpenKeyEx 函数来打开注册表项。
  • lpValueName:指定要删除的值的名称,它是一个以 null 结尾的字符串。

返回值:

  • 如果函数调用成功,返回 ERROR_SUCCESS(0)。
  • 如果函数调用失败,返回一个非零的错误代码,可以使用 FormatMessage 函数来获取错误信息。

示例代码:

#include <Windows.h>
#include <stdio.h>

int main() {
    HKEY hKey;

    // 打开注册表项 HKEY_CURRENT_USER\Software\MyApp
    LONG result = RegOpenKeyEx(
        HKEY_CURRENT_USER,
        TEXT("Software\\MyApp"),
        0,
        KEY_WRITE,
        &hKey
    );

    if (result == ERROR_SUCCESS) {
        const TCHAR* valueName = TEXT("MyValue");

        // 删除指定值
        result = RegDeleteValue(hKey, valueName);

        if (result == ERROR_SUCCESS) {
            printf("Registry value deleted successfully.\n");
        }
        else if (result == ERROR_FILE_NOT_FOUND) {
            printf("Registry value not found.\n");
        }
        else {
            printf("Failed to delete registry value.\n");
        }

        // 关闭注册表项句柄
        RegCloseKey(hKey);
    }
    else {
        printf("Failed to open registry key.\n");
    }

    return 0;
}

四、列举指定注册表键下的子键(子项)的名称

RegEnumKeyEx函数

RegEnumKeyEx 函数是用于列举指定注册表键下的子键(子项)的名称。通过该函数,您可以获取注册表项的子项列表,以便进一步处理或检查

函数原型:

LONG RegEnumKeyEx(
  HKEY       hKey,            // 指定一个打开的注册表项的句柄
  DWORD      dwIndex,         // 指定要检索的子项的索引
  LPTSTR     lpName,          // 用于接收子项名称的缓冲区
  LPDWORD    lpcName,         // 接收子项名称的缓冲区大小(字符数)
  LPDWORD    lpReserved,      // 保留参数,通常为 NULL
  LPTSTR     lpClass,         // 用于接收子项的类名称的缓冲区
  LPDWORD    lpcClass,        // 接收类名称的缓冲区大小(字符数)
  PFILETIME  lpftLastWriteTime // 接收子项的最后写入时间
);

参数解释:

  • hKey:指定一个打开的注册表项的句柄,您可以使用 RegOpenKeyEx 函数来打开注册表项。
  • dwIndex:指定要检索的子项的索引,从 0 开始计数。
  • lpName:指向接收子项名称的缓冲区的指针。
  • lpcName:指向一个 DWORD 类型的变量的指针,用于指定 lpName 缓冲区的大小(字符数)。
  • lpReserved:保留参数,通常为 NULL
  • lpClass:指向接收子项的类名称的缓冲区的指针。可以为 NULL
  • lpcClass:指向一个 DWORD 类型的变量的指针,用于指定 lpClass 缓冲区的大小(字符数)。
  • lpftLastWriteTime:指向 FILETIME 结构的指针,用于接收子项的最后写入时间。可以为 NULL

返回值:

  • 如果函数调用成功,返回 ERROR_SUCCESS(0)。
  • 如果函数调用失败,返回一个非零的错误代码,可以使用 FormatMessage 函数来获取错误信息。

示例代码:

#include <Windows.h>
#include <stdio.h>

int main() {
    HKEY hKey;
    DWORD index = 0;
    TCHAR subkeyName[MAX_PATH];
    DWORD subkeyNameSize = MAX_PATH;

    // 打开注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
    LONG result = RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,
        TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
        0,
        KEY_READ,
        &hKey
    );

    if (result == ERROR_SUCCESS) {
        printf("Subkeys under HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion:\n");

        // 枚举子项名称
        while (true) {
            result = RegEnumKeyEx(
                hKey,
                index,
                subkeyName,
                &subkeyNameSize,
                NULL,
                NULL,
                NULL,
                NULL
            );

            if (result == ERROR_SUCCESS) {
                //printf("%s\n", subkeyName);
                wprintf(L"%s\n", subkeyName);
                index++;
                subkeyNameSize = MAX_PATH;
            }
            else if (result == ERROR_NO_MORE_ITEMS) {
                // 所有子项都已枚举完毕
                break;
            }
            else {
                printf("Failed to enumerate subkey.\n");
                break;
            }
        }

        // 关闭注册表项句柄
        RegCloseKey(hKey);
    }
    else {
        printf("Failed to open registry key.\n");
    }

    return 0;
}

  

标签:HKEY,函数,hKey,编程,指定,Win32,句柄,注册表
From: https://www.cnblogs.com/TechNomad/p/17717369.html

相关文章

  • 当一个接口需要调用多个其他服务的接口时,可以使用异步编程来实现并发调用,以提高效率
    usingSystem;usingSystem.Collections.Generic;usingSystem.Threading.Tasks;publicclassOrderController{publicasyncTask<OrderInfo>GetOrderInfo(intorderId){//并发调用多个接口Task<UserInfo>getUserInfoTask=GetUserInfoAsync(orderId);Task......
  • Java学习之路--oop--面向对象编程(封装、继承、多态)01
    packagecom.oop.demo01;importjava.io.IOException;//什么是面向对象/*面向对象编程:Object-OrientedPrograming(简称OOP)面向对象编程的本质就是:**以类的方式组织代码,以对象的组织(封装)数据抽象三大特性:封装继承多态*///Demo01-类publicclassDemo01{publicstaticvoid......
  • Java学习之路--oop--面向对象编程(封装、继承、多态)03
    packagecom.oop.demo04;/*封装:设计程序要追求“高内聚,低耦合”属性私有,get/set封装的意义:1.提高程序的安全性,保护数据2.隐藏代码的实现细节3.统一接口4.系统的可维护性增加*/publicclassApplication{publicstaticvoidmain(String[]args){Students1=newS......
  • Java学习之路--oop--面向对象编程(封装、继承、多态)02
    packagecom.oop.demo02;//一个项目应该只存一个main方法publicclassApplication{publicstaticvoidmain(String[]args){//new实例化了一个对象Personperson=newPerson("无言");System.out.println(person.name);}}////类:抽象......
  • Java编程学习笔记01
    网络编程笔记2023.2.28---2023.3.10/*1.1什么是计算机网络计算机网络是指将==地理位置不同==的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理协调下,实现资源互通和信息共享传递的计算机系统//打电话--连接--......
  • Java编程学习笔记02
    GUI编程2023.3.11--现在Gui编程已经被淘汰,用的很少很少一、简介:Gui的核心技术:Swing和AWT原因:1.界面不美观2.需要jre环境!为什么要学习?1.可以写出自己心中想要的一些小工具2.工作时候,有可能需要维护到Swing界面,概率极小3.了解MVC架构,了解监听!怎么学?怎么用组件(Component):窗......
  • 结对编程队友个人项目互评
    一、项目简介1.项目名称:中小学数学卷子自动生成程序2.项目作者:党郑骅霖3.项目编程语言:Java 二、项目分析1.类图 2.流程图3.代码分析核心方法解析:1.`main`方法:-程序的入口点,包含主要的程序逻辑。-初始化已有用户列表,接收用户输入,允许用户登录,并根据用户的......
  • 中小学数学卷子自动生成程序——结对编程队友互评
    结对编程队友互评代码:软件2105何志成评价:软件2105陈相彤一、题目介绍用户:小学、初中和高中数学老师。功能:1、命令行输入用户名和密码,两者之间用空格隔开(程序预设小学、初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根据账户类型显示“当前选择为XX出题”,XX为......
  • 【结对编程互评-C++】中小学数学卷子自动生成程序
    【结对编程互评-C++】中小学数学卷子自动生成程序项目名称:中小学数学卷子自动生成程序编程语言:C++代码作者:李义评价人:张恒硕目录[1.项目要求][1.1目标用户][1.2实现功能][2.代码分析][3.功能测试][3.1登录功能测试][3.2出题功能测试][4.优缺点分析与总结]......
  • Python异步编程高并发执行爬虫采集,用回调函数解析响应
    一、问题:当发送API请求,读写数据库任务较重时,程序运行效率急剧下降。异步技术是Python编程中对提升性能非常重要的一项技术。在实际应用,经常面临对外发送网络请求,调用外部接口,或者不断更新数据库或文件等操作。这这些操作,通常90%以上时间是在等待,如通过REST,gRPC向服务器发送请......