如何恢复注册表项的所有元素? (上次写入时间,类型,值,名称...)这是正确的方法吗?

时间:2019-04-26 15:07:35

标签: c++ windows winapi registrykey

我想恢复注册表项的所有元素。 Windows API RegOpenEX和RegEnumKeyEx的方法。但是我不确定这是正确的方法。这是我的代码示例,是否应该使用这两种方法来检索此信息?

HKEY RegHkey;
Long RC=0;
DWORD a=0;
DWORD TMP=255;
FILETIME filetime;
LPWSTR lpName=nullptr;
LPWSTR lpClass=nullptr;
DWORD cchClasss=0;

RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\",0,KEY_READ,&RegHkey);

while(RC != ERROR_NO_MORE_ITEMS)
{
  RC=RegEnumKeyEx(RegHkey, a, lpName, &TMP, nullptr, lpClass, &cchClass, &filetime);
   if(RC==ERROR_SUCCESS)
   {
      std::cout<<"type= "<<cchClass<<std::endl;
     //etc...

   }
   a++;
}

如果RC == ERROR_SUCCESS,我想检索类型,值和last_write_time。...这是正确的方法吗?

1 个答案:

答案 0 :(得分:1)

不幸的是,这段代码中几乎所有内容都是错误的。

LPWSTR lpName=nullptr;
LPWSTR lpClass=nullptr;

每当函数参数的文档中显示诸如“ 指向缓冲区的指针”之类的内容时,您都需要提供已分配的缓冲区。

// The {} brackets zero-initialize the buffers.
wchar_t szName[255]{};
wchar_t szClass[255]{};
DWORD TMP=255;
DWORD cchClasss=0;

cchClass设置为零是错误的。您必须告诉该函数实际的缓冲区大小(可以在其中存储多少个字符,包括“ \ 0”)。变量TMP没有有意义的名称,cchName将更加一致:

// No need to hardcode the array size.
DWORD cchName  = ARRAYSIZE(szName);
DWORD cchClass = ARRAYSIZE(szClass);
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\",0,KEY_READ,&RegHkey);

缺少对功能是否成功的检查。由于多种原因,打开注册表项可能会失败。 G。权限不足:

DWORD res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\",0,KEY_READ,&RegHkey);
if(res == ERROR_SUCCESS)
{
    // do something with the registry key
} 
while(RC != ERROR_NO_MORE_ITEMS)

RegEnumKeyEx出于除枚举之外的其他原因而失败时,您将陷入无限循环。正确的条件是RC == ERROR_SUCCESS

  RC=RegEnumKeyEx(RegHkey, a, lpName, &TMP, nullptr, lpClass, &cchClass, &filetime);

注册表项SOFTWARE\Microsoft\Windows\CurrentVersion\Run\的子代是值,因此您必须使用RegEnumValueW()

请确保在完成注册表项后也调用RegCloseKey()