SHDeleteKey 和 RegDeleteTree 有什么区别?

Che*_* OT 5 c c++ windows winapi

注册删除树

  • 描述:递归删除指定键的子键和值。

  • 签名: LONG WINAPI RegDeleteTree(HKEY, LPCTSTR)

  • 最低支持:Vista

  • 包括: Winreg.h/Advapi32.lib

删除键

  • 描述:删除一个子项及其所有后代。此函数从注册表中删除键和所有键的值。

  • 签名: LSTATUS SHDeleteKey (HKEY, LPCTSTR)

  • 最低支持:XP

  • 包括: Shlwapi.h/Shlwapi.lib

看起来它们都用于递归删除注册表。并且它们的参数签名几乎相同。

RegDeleteTree的只是改良版本SHDeleteKey使用不同的名称?我应该改用更新的RegDeleteTree还是它们之间有一些区别?

ahm*_*md0 6

SHDeleteKey和之间的主要区别RegDeleteTree是:

1)他们删除注册表项的方式。例如:

SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Company\\App\\Settings");
Run Code Online (Sandbox Code Playgroud)

将删除一切Settings的关键,包括Settings密钥本身。尽管:

RegDeleteTree(HKEY_CURRENT_USER, L"Software\\Company\\App\\Settings");
Run Code Online (Sandbox Code Playgroud)

将在删除所有Settings按键,除了Settings键。它将保持为空。

2)RegDeleteTree允许指定 WOW64 密钥重定向如下:

HKEY hKey = NULL;
if(RegOpenKeyEx(HKEY_CURRENT_USER,
    L"Software\\Classes\\CLSID\\{-my-guid-}", 0, 
    DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_SET_VALUE |
    KEY_WOW64_64KEY, //For WOW64, delete only 64-bit redirected part
    &hKey) == ERROR_SUCCESS)
{
    if(RegDeleteTree(hKey, NULL) == ERROR_SUCCESS)
    {
        //Deleted everything in HKEY_CURRENT_USER\Software\Classes\CLSID\{-my-guid-}
    }

    RegCloseKey(hKey);
}
Run Code Online (Sandbox Code Playgroud)

3)RegDeleteTree与其余的注册表函数驻留在相同的低级 DLL 中,即Advapi32.dll,虽然SHDeleteKey在 Windows Shell 的Shlwapi.dll. 这种区别对于某些类型的服务可能很重要。

4)RegDeleteTree在较旧的操作系统上不可用,例如 Windows XP SP3、Server 2003。它仅在 Vista 和 Server 2008 之后可用。

  • 很好的答案,但(2)严格来说并不正确 - 您可以将使用 RegOpenKeyEx 打开的密钥的句柄传递给 SHDeleteKey (从而允许您使用 KEY_WOW64_64KEY 标志)... (2认同)

Abh*_*eet 4

恕我直言,以及所提供的文档,我认为差异在于;

  • API 移至不同的 dll,原因可能是删除了 OP 所评论的单个功能的 shell 库依赖性。
  • 如果键有任何值,RegDeleteTree 需要您具有 KEY_SET_VALUE 权限。

Christian.K 给出的链接很好地总结了这一点。我在答案中包含了该博客的一些重要部分;

在过去的几个 Windows 版本中,有大量的“shell”帮助程序 API 已经从 shell 中“提升”出来并转变为 Win32 核心 API。原因之一是核心操作系统部门的一些团队发起的持续的架构分层工作。

SHRegGetValue API 是分层问题标记为更适合核心操作系统功能的 API 之一 - 分层团队所做的分析表明,操作系统中的许多低级组件正在调用 shell DLL,因为 shell 助手函数提供了一些较低层中不存在的便利功能。

结果,许多 shell API 被重新创建为 kernel32 API。