最近在写一个小项目的时候需要能够编辑注册表相关的信息,过程中发现windows没有给能够修改注册表项名称的API接口(反正我没找到),只能找到创建/删除之类的API(包括正常Reg系列API和SH系列API)。万般无奈之下,我发现API中的导入导出函数可以直接覆盖旧的目标注册表项,通过Save/LoadKey(RestoreKey)的方法将旧的注册表项内的内容覆盖到新创建的项上从而实现了注册表项的重命名功能。(我称之为SL大法)以下就是实现的界面(我是使用MFC实现的).

----重命名后----->

下面是具体实现的过程

首先是注册表的删除键和所有子键的封装,使用递归的方式可以实现

PS:函数中有个PrintError函数是我用来输出错误码的,可以无视和注释掉就行了

//递归删除键和所有子键
BOOL RegOpt::DoDeleteRegItem(HKEY rootKey,CString szRegPath)
{BOOL bFlag = TRUE;HKEY hKey;do {//打开注册表if ( ERROR_SUCCESS != RegOpenKeyEx( rootKey, szRegPath.GetBuffer (), 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey )){PrintError ("RegOpenKeyEx ERR!");bFlag = FALSE;break;}//获取注册表子键信息,判断是否有子键TCHAR szSubKey[MAX_KEY_LENGTH]; //子键名称DWORD dwName = MAX_KEY_LENGTH;   //名称大小//是否有子键,如果有则递归查找,这里要注意,index不能自增,因为一旦删除了一个键,其余键的序号就会自己减一,所以不断删除0就可以了int index = 0;while (ERROR_NO_MORE_ITEMS != RegEnumKey(hKey,index,szSubKey,dwName)){CString tmp = szRegPath + TEXT('\\') + szSubKey;bFlag = DoDeleteRegItem (rootKey,tmp);}//递归删除失败,退出递归if (!bFlag){break;}//删除当前键int errcode;if (ERROR_SUCCESS != (errcode = RegDeleteKey(rootKey,szRegPath))){PrintError ("RegDeleteKey ERR!",errcode);bFlag = FALSE;break;}} while (FALSE);RegCloseKey (hKey);return bFlag;
}

然后就是重命名的操作了

//重命名注册表项
BOOL RegOpt::RenameRegItem(CString szRegPath,CString szNewName)
{BOOL bFlag = TRUE;HKEY hKey;do {if (!GetPrivilege()){bFlag = FALSE;break;}if (szRegPath.IsEmpty () || szNewName.IsEmpty ()){bFlag = FALSE;break;}//分离主键和路径HKEY rootKey;for (int i = 0;i < 5;i ++){if (szRegPath.Find (szRegMainKey[i]) != -1){rootKey = RegMainKey[i];szRegPath.Delete (0,szRegMainKey[i].GetLength () + 1);break;}}if (ERROR_SUCCESS != RegOpenKeyEx(rootKey, szRegPath, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey)){bFlag = FALSE;PrintError ("RegOpenKeyEx ERR!");break;}//SL大法保平安,重命名CString szFilePath = TEXT("SLDF");保存注册表键值到文件int errcode;if (ERROR_SUCCESS != (errcode = RegSaveKey(hKey, szFilePath, NULL))){bFlag = FALSE;PrintError ("RegSaveKey ERR!",errcode);break;}//递归删除旧项if (!DoDeleteRegItem (rootKey,szRegPath)){bFlag = FALSE;PrintError ("DoDeleteRegItem ERR!");break;}//关闭旧键RegCloseKey (hKey);index = szRegPath.ReverseFind ('\\');szRegPath.Delete (index + 1,szRegPath.GetLength () - index);//打开新键   if (ERROR_SUCCESS != RegOpenKeyEx(rootKey, szRegPath, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey)){bFlag = FALSE;PrintError ("RegOpenKeyEx ERR!");break;}HKEY newKey;//创建新项if (ERROR_SUCCESS != RegCreateKey(hKey, szNewName, &newKey)){bFlag = FALSE;PrintError ("RegCreateKey ERR!");break;}//从文件中加载注册表键值errcode;if (ERROR_SUCCESS != (errcode = RegRestoreKey(newKey, szFilePath, REG_FORCE_RESTORE))){bFlag = FALSE;PrintError ("RegRestoreKey ERR!",errcode);break;}RegCloseKey (newKey);//删除文件if (!DeleteFile(szFilePath)){bFlag = FALSE;PrintError ("DeleteFile ERR!");break;}} while (FALSE);RegCloseKey (hKey);return bFlag;
}

具体的步骤就是先将旧键导出到文件,然后删除旧键,然后在原位置用新名字创建新键,然后再用导入函数直接覆盖,从而实现注册表键的重命名操作,最后别忘了将之前导出的文件删除就OK了(以便下次重命名,如果这个文件存在的话,导出函数会失败).

其中GetPrivilege()  函数使用来获取相关权限的,具体实现如下

BOOL RegOpt::GetPrivilege()
{BOOL bFlag = TRUE;do {//设置权限导入导出注册表HANDLE hToken,hToken1,hToken2;TOKEN_PRIVILEGES tkp,tkp1,tkp2;if(!OpenProcessToken (GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken)){PrintError ("OpenProcessToken ERR!");bFlag = FALSE;break;}if(!LookupPrivilegeValue( NULL, SE_BACKUP_NAME, &tkp.Privileges[0].Luid)){PrintError ("LookupPrivilegeValue ERR!");bFlag = FALSE;break;}tkp.PrivilegeCount = 1;tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if(!AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, PDWORD(NULL))){PrintError ("AdjustTokenPrivileges ERR!");bFlag = FALSE;break;}if(GetLastError () == ERROR_NOT_ALL_ASSIGNED || GetLastError () != ERROR_SUCCESS ){PrintError ("AdjustTokenPrivileges Failed");bFlag = FALSE;break;}if(!OpenProcessToken (GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken1)){PrintError ("OpenProcessToken ERR!");bFlag = FALSE;break;}if(!LookupPrivilegeValue( NULL, SE_RESTORE_NAME, &tkp1.Privileges[0].Luid)){PrintError ("LookupPrivilegeValue ERR!");bFlag = FALSE;break;}tkp1.PrivilegeCount = 1;tkp1.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if(!AdjustTokenPrivileges( hToken1, FALSE, &tkp1, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, PDWORD(NULL))){PrintError ("AdjustTokenPrivileges ERR!");bFlag = FALSE;break;}if(GetLastError () == ERROR_NOT_ALL_ASSIGNED || GetLastError () != ERROR_SUCCESS ){PrintError ("AdjustTokenPrivileges Failed");bFlag = FALSE;break;}if(!OpenProcessToken (GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken2)){PrintError ("OpenProcessToken ERR!");bFlag = FALSE;break;}if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &tkp2.Privileges[0].Luid)){PrintError ("LookupPrivilegeValue ERR!");bFlag = FALSE;break;}tkp2.PrivilegeCount = 1;tkp2.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if(!AdjustTokenPrivileges( hToken2, FALSE, &tkp2, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, PDWORD(NULL))){PrintError ("AdjustTokenPrivileges ERR!");bFlag = FALSE;break;}if(GetLastError () == ERROR_NOT_ALL_ASSIGNED || GetLastError () != ERROR_SUCCESS ){PrintError ("AdjustTokenPrivileges Failed");bFlag = FALSE;break;}} while (FALSE);return bFlag;
}

我主要申请了SE_BACKUP_NAME和SE_DEBUG_NAME权限用于导入导出和注册表修改操作。

之所以没用LoadKey是因为这个API在进行某些键值的导入时会出错,好像是不支持,所以我改用了RestoreKey。

以上便是我使用SL大法实现注册表键重命名的过程了。虽然有些麻烦,但总归是实现了……

Windows平台下 C++注册表项重命名实现相关推荐

  1. Internet Explorer 设置 注册表中设置IE(Windows安全设置之注册表项)

    Windows安全设置之注册表项 在IE4.0以上的版本中,IE的安全设置一般都存贮在这两个地方: 1.HKEY_CURRENT_USER\Software\Microsoft\Windows\Cur ...

  2. 管理员获得所有权_在Windows 7中获得注册表项的所有权

    管理员获得所有权 We have previously written about how to take ownership of files and folders in Windows 7, b ...

  3. 在Windows 7下删除注册表项时,权限不足

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\vid_**** 注册表项下的 properties 子项(以及其下的子项)为 system  ...

  4. windows下批处理删除文件及注册表项

    1.windows下批处理删除注册表项 假如我要清除WinRAR的历史记录,可以新建个批处理文件, 然后在里面加入如下文字: reg delete HKEY_CURRENT_USER/Software ...

  5. 服务器iis7.5 配置文件,使用注册表项 - Internet Information Services | Microsoft Docs

    Internet 信息服务使用的注册表项的说明 07/21/2020 本文内容 本文介绍了 Microsoft Internet Information Services (IIS) 在 Window ...

  6. 记录Windows 的一些基础知识(包括基础命令,文件系统,注册表项)

    Windows基础命令 ## windows输入命令```powershell win+R 打开cmd 右键管理员运行 目录和文件操作 目录分为相对路径和绝对路径 相对路径(以当前为起点) " ...

  7. 64位Windows系统注册表的 32 位注册表项和64 位注册表项

    64 位版本 Windows 中的注册表分为 32 位注册表项和 64 位注册表项.许多 32 位注册表项与其相应的 64 位注册表项同名,反之亦然. 64 位版本 Windows 包含的默认 64 ...

  8. Qt:Windows编程—Qt实现注册表启动项管理

    Qt实现注册表启动项管理 前言 Windows的开机启动项在很多地方都有设置,这次我们在注册表 子键"HKEY_LOCAL_MACHINE\Software\Microsoft\Window ...

  9. C#设置开机启动时报错,提示“对注册表项“HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run访问被拒绝”

    参考文章 C#如何设置开机启动 C#设置开机启动时报错,提示"对注册表项"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Current ...

最新文章

  1. 【每日一题】航班预订统计
  2. Reading Club week 3 prepare document
  3. oracle awr报告提取,oracle AWR报告提取分析
  4. ORB-SLAM2中四叉树管理特征点
  5. oracle outln用户,Oracle用户解锁
  6. 程序员“苦逼值”测试,分数越高越苦逼
  7. 能力共进、价值共赢,华为传媒携手生态伙伴推动行业数字化转型和智慧化升级
  8. Python面向对象基础一
  9. 有关linux信号汇总
  10. 阿里云部署java web
  11. mysql常见函数的实列
  12. 视频消重软件大全 视频md5修改器哪个好用
  13. echarts官网在线编辑的图表如何导出svg
  14. xbox键位测试软件,xbox手柄测试软件
  15. 易语言mysql 记录集_求一个易语言返回mysqlcha询结果记录集的例子
  16. macbook重装系统 选择方案_Mac重装系统详解,教你mac抹掉磁盘重装系统!
  17. joomla网页加速插件
  18. 奶瓶(beini) 又一蹭网神器 1.2.2增强版带600万密码字典
  19. 前端 js 深浅拷贝
  20. Unity 3D 游戏与编程

热门文章

  1. 用Photoshop制作一张“油画”
  2. BLM模型:解决问题的前提是定义问题
  3. (VQA)LRTA: A Transparent Neural-Symbolic Reasoning Framework with Modular Supervision for Visual Que
  4. ps有一款比较好用的插件也就是调色插件用过吗
  5. 闪存卡提示格式化怎么办?里面的数据怎么恢复
  6. 音频合并的步骤有哪些
  7. linux系统下如何解压RAR文件软件rarforlinux
  8. c语言开发的cli,Package - cyy-cli
  9. 关于sui mobile和light7的一些看法
  10. springboot项目结构_从零搭建Spring Boot脚手架(1):开篇以及技术选型