递归删除注册表键

3

我需要在Windows Mobile 6下删除Windows注册表中的子树。RegDeleteTree函数不可用,而SHDeleteKey在WM6 SDK的任何静态库中(显然)都不可用,尽管在shlwapi.h中声明可用。
我试图从shlwapi.dll获取它,例如

    typedef DWORD (__stdcall *SHDeleteKey_Proc) (HKEY, LPCWSTR);
    SHDeleteKey_Proc procSHDeleteKey; 
    HINSTANCE shlwapidll = ::LoadLibrary(_T("shlwapi.dll"));
    if(shlwapidll) {
    procSHDeleteKey = 
            (SHDeleteKey_Proc)GetProcAddress(shlwapidll,_T("SHDeleteKeyW"));
        ASSERT(procSHDeleteKey);
    }

但是我遇到了断言错误。
在Windows Mobile下,有没有一种好的方法可以递归地删除一个注册表键(无论是否为空)?

3个回答

6

我想我在MSDN上找到了答案。不过,让我困惑的是,这个功能在SDK中不可用...
为了记录,我也把来自MSDN的代码放在这里:

//*************************************************************
//
//  RegDelnodeRecurse()
//
//  Purpose:    Deletes a registry key and all it's 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 it's 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);
}

0
< p > GetProcAddress 的第二个参数是 LPCSTR(也就是说,它不是 LPCTSTR)。因此,请删除 _T() 并尝试以下代码:

GetProcAddress(shlwapidll, "SHDeleteKeyW");

这有助于解决问题吗?


'GetProcAddressW':无法将参数2从'const char [13]'转换为'LPCWSTR'。 - E Dominique
你说得完全正确 - 在 Windows CS 上,确实有 <code>GetProcAddress</a> 的 A 版本和 W 版本,但在“普通”的 Windows 上却没有。不知道为什么... - Ashutosh Mehra
几乎每个Windows CE中的API都是Unicode版本。CE没有GetProcAddress的ASCII版本。 - ctacke

-3
你正在寻找RegDeleteTree()函数。只需用它替换RegDeleteKey即可。
显然,他们花了一些时间才弄清楚,所以如果你想支持XP或更早的版本,你需要有自己的实现。

好的,问题明确是关于Windows Mobile的,其中RegDeleteTree是不可用的(正如我在问题中所述...)。 - E Dominique

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