繁体   English   中英

C ++读取注册表

[英]C++ read Registry

我尝试在我的NPAPI插件中读取注册表:

bool ScriptablePluginObject::Invoke(NPObject* obj, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result) {
    ScriptablePluginObject *thisObj = (ScriptablePluginObject*) obj;
    char* name                      = npnfuncs->utf8fromidentifier(methodName);
    LPCWSTR game_path               = getRegKey(L"SOFTWARE\\World of RPG", L"Path");

    MessageBox(NULL, game_path, L"Debugging", MB_TOPMOST);

    /* ... */
}

LPCWSTR ScriptablePluginObject::getRegKey(LPCWSTR location, LPCWSTR name) {
    HKEY hKey;
    LPBYTE folder   = new BYTE[MAX_PATH];
    DWORD dwSize    = sizeof(folder);
    long registry   = RegOpenKeyEx(HKEY_LOCAL_MACHINE, location, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
    long entry      = RegQueryValueEx(hKey, name, NULL, REG_NONE, folder, &dwSize);

    if(registry != ERROR_SUCCESS) {
        return L"Error1";
    }

    if(entry != ERROR_SUCCESS) {
        return L"Error2";
    }

    RegCloseKey(hKey);
    folder[dwSize / sizeof(folder[0])] = '\0';
    return (LPCWSTR) folder;
}

但每次调用Error2都会返回它。 我尝试了很多更改:

  • 更改路径(以开始和/或结束\\\\
  • 改变参数

我想获取HKEY_LOCAL_MACHINE\\SOFTWARE\\World of RPG\\Path

在此处输入图片说明

有人可以帮助我吗? 我做错了什么?

getRegKey() ,您的folder变量是一个指针,因此sizeof(folder)为4(如果编译为32位)或8(如果编译为64位)。 因此RegQueryValueEx()失败,并显示ERROR_MORE_DATA错误代码。

您还为数组使用了错误的数据类型。 您需要使用WCHAR而不是BYTE

更改此:

LPBYTE folder   = new BYTE[MAX_PATH];
DWORD dwSize    = sizeof(folder);

对此:

LPWSTR folder   = new WCHAR[MAX_PATH];
DWORD dwSize    = sizeof(WCHAR) * MAX_PATH;

这么说,您泄漏的是folder指向的内存,因为您从未delete[]

这是我在上面的评论中提到的示例:

#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

LSTATUS ReadRegistry ( LPCWSTR sPath, LPCWSTR sKey, LPWSTR pBuffer, DWORD *pBufferSize );

int _tmain(int argc, _TCHAR* argv[])
{
    const int BUFFER_SIZE = 1024;

    WCHAR sBuffer[BUFFER_SIZE]; // 2048 bytes
    DWORD nBufferSize = BUFFER_SIZE * sizeof ( WCHAR );

    ZeroMemory ( sBuffer, nBufferSize );
    LSTATUS nResult = ReadRegistry ( L"SOFTWARE\\7-Zip", L"Path64",
        sBuffer, &nBufferSize );

    // check nResult for ERROR_SUCCESS to know if the call succeeded or not

    return 0;
}

LSTATUS ReadRegistry ( LPCWSTR sPath, LPCWSTR sKey, LPWSTR pBuffer, LPDWORD pBufferSize )
{
    HKEY hKey;
    LSTATUS nResult = ::RegOpenKeyEx ( HKEY_LOCAL_MACHINE, sPath,
        0, KEY_READ | KEY_WOW64_64KEY, &hKey );

    if ( nResult == ERROR_SUCCESS )
    {
        nResult = ::RegQueryValueEx ( hKey, sKey, NULL, NULL,
            (LPBYTE) pBuffer, pBufferSize );

        RegCloseKey ( hKey );
    }

    return ( nResult );
}

请注意, ReadRegistry函数如何不分配内存-它需要一个缓冲区,并用数据填充它。 如果始终让调用者分配内存,则处理内存要容易得多。 如果被调用方分配了内存,则调用方可能不知道如何分配内存,也可能不知道如何释放内存。 (当然,您始终可以假设使用newdelete但是如果只有一侧一致地执行此操作,则事情会更简单。如果调用方分配了内存,它将知道如何释放它。被调用方只需要将数据放入分配的空间。

另外,请注意在继续下一个调用之前如何检查API函数的返回值-这很重要,因为这会告诉您是否获得了有用的注册表句柄以及是否需要关闭它。

(此示例实际上只是C,不是C ++,但仍然适用。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM