删除注册表键 - MSDN示例中出现错误

3

这篇 MSDN文章旨在演示如何删除具有子键的注册表键,但代码存在缺陷。

代码中的一行:

StringCchCopy (lpEnd, MAX_PATH*2, szName);

导致异常,原因是尝试复制超出lpEnd缓冲区的范围。我尝试通过用以下内容替换该行来纠正解决方案

size_t subKeyLen = lstrlen(lpSubKey);
size_t bufLen = subKeyLen + lstrlen(szName)+1;
LPTSTR buf = new WCHAR[bufLen];
StringCchCopy(buf,bufLen,lpSubKey);
StringCchCopy(buf+subKeyLen,lstrlen(szName)+1,szName);
buf[bufLen-1]='\0';

由于目标平台和开发平台不同,我无法逐步执行代码,但从我放置在代码中的日志来看,它似乎只是冻结了,但没有抛出异常。

令人沮丧的是 MSDN 文章是错误的...你会认为它们会被检查。

有什么想法可以纠正这个问题吗?

谢谢。


2
是的,这是示例中的一个错误。应该是 StringCchCopy(lpEnd, MAX_PATH * 2 - (lpEnd - lpSubKey), szName),或者更简单一些,*lpEnd = 0; StringCchCat(lpSubKey, MAX_PATH * 2, szName) - Raymond Chen
2个回答

1

仅仅这个变化是不够的。在它后面的那行代码:

        if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
            break;

还需要进行更改。lpSubKey需要被替换为buf,因为它现在包含了完整的键。

虽然这可能是显而易见的,但一定要确保在清理过程中释放(删除)buf

然而,为了正确性,似乎最好只是修复原始代码行,将其更改为传递正确的长度(因为我相信注册表中的最大键长为255):

StringCchCopy (lpEnd, MAX_PATH*2 - lstrlen(lpSubKey), szName);

1

如果您不介意增加一个依赖项 Shlwapi.dll,那么您可以使用SHDeleteKey更容易。如果您只针对Vista+,则另一种选择是RegDeleteTree(位于Advapi32.dll中)。


抱歉,我知道我已经标记这个问题为已解决,但我遇到了一个问题。当在HKEY_CURRENT_USER中测试时,它可以正常工作,但是当尝试删除HKEY_LOCAL_MACHINE中的键时,它没有任何效果。 - Bill Walton
1
@BillWalton,你可能没有修改HKEY_LOCAL_MACHINE中任何内容的权限。如果这是你必须要做的事情,你需要以提升的权限运行。 - Mark Ransom
1
你是否拥有修改HKEY_LOCAL_MACHINE的正确权限?你需要以管理员身份运行。 - Mike Kwan
谢谢Mark,只要我以管理员身份登录,我就会拥有提升的特权吗?我注意到一个奇怪的事情是,当我在HKEY_CURRENT_USER中删除密钥时,我从SHDeleteKey得到了相同的返回值1,这在winerror.h中被定义为ERROR_INVALID_FUNCTION。然而它仍然删除了HKEY_CURRENT_USER中的密钥,而不是HKEY_LOCAL_MACHINE中的密钥。 - Bill Walton
@BillWalton,仅拥有管理员权限是不够的。您需要向程序添加清单以请求提升,Windows 将在每次启动程序时显示 UAC 对话框。 - Mark Ransom
我也发现每个键都有权限,因此必须逐个遍历每个键并设置权限以允许管理员删除,然后管理员才能删除,这真的很繁琐。 - Motomotes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接