C ++ RegGetValue函数输出错误

时间:2016-07-01 01:23:08

标签: c++ visual-studio-2015 64-bit registry windows-10

我正在尝试通过检查regedit搜索注册表的卸载文件夹,查找我知道的给定程序。我的函数当前找到程序,但由于某种原因,它不会从RegGetValue函数更新输出值,直到下一次迭代。因此它打印正确的注册表项及其前身。有什么想法吗?

如果重要的话,我使用的是使用Visual Studio 2015的英特尔处理器的Windows 10 64位工作站。

的main.cpp

#include "Registry.h"
#include <Windows.h>
#include <tchar.h>

void main()
{
    Registry test(_T("Microsoft SQL Server 2012 Native Client "));
}

Registry.h

#pragma once

#include <Windows.h>
#include <string>

#define REG_PATH L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
#define X86REG_PATH L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"

class Registry
{
public:
    Registry(TCHAR* name);
    ~Registry();
    TCHAR* findGUID();
    TCHAR* getDisplayName();
    TCHAR* getGUID();
    TCHAR* getVersion();
    TCHAR* getPublisher();
    TCHAR* getInstallDate();
private:
    TCHAR* displayName;
    TCHAR* guid;
    TCHAR* version;
    TCHAR* publisher;
    TCHAR* installDate;
};

Registry.cpp

#pragma once

#include "Registry.h"
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <fstream>

Registry::Registry(TCHAR* name)
{
    HKEY hKey;
    LPCTSTR lpSubKey;
    DWORD ulOptions;
    REGSAM samDesired;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PATH, NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        std::wofstream file;
        file.open("test.txt");
        int index = 0;
        HKEY UninstallDir = hKey;
        TCHAR subKey[MAX_PATH];
        DWORD subKeySize = MAX_PATH;
        while (RegEnumKeyEx(hKey, index, subKey, &subKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            HKEY guid;
            TCHAR* guidPath = new TCHAR[MAX_PATH];
            _tcscpy_s(guidPath, MAX_PATH, REG_PATH);
            _tcscat_s(guidPath, MAX_PATH, subKey);
            TCHAR compareName[MAX_PATH];
            DWORD nameSize;
            //print all registry keys to file
            file << index << ": " << guidPath << std::endl;
            int test;
            RegGetValue(HKEY_LOCAL_MACHINE, guidPath, _T("DisplayName"), RRF_RT_ANY, NULL, &compareName, &nameSize);
            //compare all registry keys *temporary to debug
            if (_tcscmp(guidPath, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{49D665A2-4C2A-476E-9AB8-FCC425F526FC}")) == 0)
            {
                std::wcout << guidPath << " found" << std::endl;
            }
            if (_tcscmp(compareName, name) == 0)
            {
                _tprintf(_T("%d: %s\n"), index, guidPath);
            }
            //print if found

            index++;
            subKeySize = 260;
        }
        file.close();
    }
    else
    {
        std::cout << "Could not open registry key." << std::endl;
    }
    //temporary to see console
    std::cin.get();
}
//still need to be completed   
Registry::~Registry()
{
}

TCHAR* Registry::findGUID()
{
    return _T("");
}

TCHAR* Registry::getDisplayName()
{
    return _T("");
}

TCHAR* Registry::getGUID()
{
    return _T("");
}

TCHAR* Registry::getVersion()
{
    return _T("");
}

TCHAR* Registry::getPublisher()
{
    return _T("");
}

TCHAR* Registry::getInstallDate()
{
    return _T("");
}

1 个答案:

答案 0 :(得分:2)

我发现您的代码存在很多问题。

您正在混合std::wcout_tprintf(),这会导致缓冲冲突。

您错误地混合了charwchar_t数据。

您在每次循环迭代时都会泄漏guidPath

您在调用nameSize时未初始化RegGetValue()

您没有设置代码来正确访问32位Wow64Node密钥。

尝试更像这样的东西。

的main.cpp

#include <Windows.h>
#include "Registry.h"

void main()
{
    Registry test(L"Microsoft SQL Server 2012 Native Client");
}

Registry.h

#pragma once

#include <Windows.h>
#include <string>

class Registry
{
public:
    Registry(const std::wstring &name);
    ~Registry();
    std::wstring findGUID();
    std::wstring getDisplayName();
    std::wstring getGUID();
    std::wstring getVersion();
    std::wstring getPublisher();
    std::wstring getInstallDate();
private:
    std::wstring displayName;
    std::wstring guid;
    std::wstring version;
    std::wstring publisher;
    std::wstring installDate;
};

Registry.cpp

#pragma once

#include <Windows.h>
#include "Registry.h"
#include <iostream>
#include <fstream>

#define REG_PATH L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"

Registry::Registry(const std::wstring &name)
{
    HKEY hKey;

    // If you want to open the 32bit Wow64Node key,
    // DO NOT open the key directly! Open the 64bit
    // key and include the KEY_WOW64_32KEY flag
    // so it will redirect to the Wow64Node key...
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PATH, NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        std::wofstream file;
        file.open(L"test.txt");

        WCHAR subKey[MAX_PATH];
        DWORD subKeySize = MAX_PATH;
        WCHAR compareName[MAX_PATH];
        DWORD nameSize;
        int index = 0;

        while (RegEnumKeyEx(hKey, index, subKey, &subKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            // print all registry keys to file
            file << index << L": " << REG_PATH << subKey << std::endl;
            int test;
            nameSize = sizeof(compareName);
            RegGetValue(hKey, NULL, L"DisplayName", RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ | RRF_ZEROONFAILURE, NULL, compareName, &nameSize);
            //compare all registry keys *temporary to debug
            if (wcscmp(subKey, L"{49D665A2-4C2A-476E-9AB8-FCC425F526FC}") == 0)
            {
                std::wcout << subKey << L" found" << std::endl;
            }
            if (name == compareName)
            {
                std::wcout << name << L" found" << std::endl;
            }
            //print if found

            index++;
            subKeySize = MAX_PATH;
        }
        file.close();
    }
    else
    {
        std::wcout << L"Could not open registry key." << std::endl;
    }

    //temporary to see console
    std::wcin.get();
}

//still need to be completed   
Registry::~Registry()
{
}

std::wstring Registry::findGUID()
{
    return L"";
}

std::wstring Registry::getDisplayName()
{
    return L"";
}

std::wstring Registry::getGUID()
{
    return L"";
}

std::wstring Registry::getVersion()
{
    return L"";
}

std::wstring Registry::getPublisher()
{
    return L"";
}

std::wstring Registry::getInstallDate()
{
    return L"";
}