2016-07-01 4 views
-1

Я пытаюсь найти папку для удаления реестра для данной программы, которую, как я знаю, проверяется путем проверки regedit. Моя функция в настоящее время находит программу, но по какой-то причине она не обновляет выходное значение из функции RegGetValue до следующей итерации. Поэтому он печатает правильный ключ реестра и его предшественник. Есть идеи?Ошибка вывода функции C++ RegGetValue

Я нахожусь на 64-разрядной рабочей станции Windows с процессорами Intel с использованием Visual Studio 2015, если это имеет значение.

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(""); 
} 
+0

файл '<< индекс << ":"<

+0

Как распечатать для отладки без утечки пути? –

+0

Вы должны «удалить []' все, что вы выделите, с помощью 'new []'. В противном случае вместо этого используйте 'std :: vector' или' std :: basic_string'. Кроме того, вы должны использовать 'std :: wcout' вместо' _printf() '. И вы не должны быть вообще 'X86REG_PATH', вместо этого используйте флаг' RRF_SUBKEY_WOW6432KEY'. –

ответ

2

Я вижу много проблем с ваш код.

Вы смешиваете std::wcout и _tprintf(), что вызывает конфликты буферизации.

Вы смешиваете данные char и wchar_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""; 
} 
+0

Хорошо. Попробует завтра на работе. Есть ли хорошая документация, которую вы рекомендуете читать? У меня нет опыта работы с определенными окнами, и я просто тренируюсь в учебных целях. –

+0

Кроме того, почему явное использование функций wchar vs _tchar? –

+0

Ваше решение сработало. Проблема, с которой я столкнулась, не была сброшена значение nameSize до максимальной длины, которую она могла видеть. Спасибо. –