RegGetValue()返回错误信息

时间:2015-09-08 06:41:51

标签: visual-c++

我正在编写一个VC ++程序,它应该从注册表中返回Java版本和Java Home。代码的目的是显示安装在单个系统中的所有JRE版本,并显示最高版本。我的系统中安装了JRE 1.5,1.6,1.7和1.8。我在显示有关版本的信息方面没有任何问题。但是当从注册表中显示JavaHome时,该路径仅适用于Java版本1.5,1.6和1.7。对于版本1.8,它显示JRE 7的路径。我尝试使用安装在每个JRE中的MSI目录中的INSTALLDIR显示路径。然后,JRE 8也存在问题。最初我认为这是用于显示所有JRE版本的循环中的错误。所以我卸载了JRE 1.8并检查了现在,JRE 1.7显示了JRE 1.6的路径。但不,不。 JRE 1.7显示了正确的路径。只有在JRE 1.8中,它才会显示1.7而不是1.8的路径。请帮帮我。我附上下面的代码。是的,检查了JRE 1.8注册表中的路径。它确实有自己的独立路径。不是JRE 1.7的路径。此外,当我尝试显示Java 1.8路径的长度时,它显示正确的长度36(因为它应该是JAVA 1.8路径的长度),即使输出显示版本1.8的路径为1.7。这是字符串比较有问题吗?请帮我解决这个问题。

#include "StdAfx.h"
#include "targetver.h"
#include "windows.h"
#include"stdio.h"
#include "sstream"
#include"string.h"
#include"tchar.h"
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
#define BUFFER 8192
char value[BUFFER];
TCHAR** versions = new TCHAR*[];
DWORD BufferSize = BUFFER;
char str1[20];
char *javapath;
void QueryKey(HKEY hKey) 
{ 
TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
DWORD    cbName;                   // size of name string 
TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
DWORD    cchClassName = MAX_PATH;  // size of class string 
DWORD    cSubKeys=0;               // number of subkeys 
DWORD    cbMaxSubKey;              // longest subkey size 
DWORD    cchMaxClass;              // longest class string 
DWORD    cValues;              // number of values for key 
DWORD    cchMaxValue;          // longest value name 
DWORD    cbMaxValueData;       // longest value data 
DWORD    cbSecurityDescriptor; // size of security descriptor 
FILETIME ftLastWriteTime;      // last write time
DWORD i, retCode;
// Get the class name and the value count. 
retCode = RegQueryInfoKey(
hKey,                    // key handle 
achClass,                // buffer for class name 
&cchClassName,           // size of class string 
NULL,                    // reserved 
&cSubKeys,               // number of subkeys 
&cbMaxSubKey,            // longest subkey size 
&cchMaxClass,            // longest class string 
&cValues,                // number of values for this key 
&cchMaxValue,            // longest value name 
&cbMaxValueData,         // longest value data 
&cbSecurityDescriptor,   // security descriptor 
&ftLastWriteTime);       // last write time 

// Enumerate the subkeys, until RegEnumKeyEx fails.
TCHAR** versions = new TCHAR*[];
for(int i = 0; i < cSubKeys; i++)
versions[i] = new TCHAR[MAX_KEY_LENGTH];
if (cSubKeys)
{
for (i=0; i<cSubKeys; i++) 
    { 
        cbName = MAX_KEY_LENGTH;
        retCode = RegEnumKeyEx(hKey, i,
                                achKey, 
                                &cbName, 
                                NULL, 
                                NULL, 
                                NULL, 
                                &ftLastWriteTime); 
            if (retCode == ERROR_SUCCESS) 
            {
                if(strlen(achKey)==8)
                {
                    printf( "\nJava Version:");
                    _tprintf(TEXT("%s"),achKey);    
                    printf( "\nJava Home:");
                    strcpy(str1,"SOFTWARE\\\\JavaSoft\\\\Java Runtime Environment\\\\");
                    strcat(str1,achKey);
                    strcat(str1,"\\\\");
                    RegGetValue(HKEY_LOCAL_MACHINE,str1, "JavaHome", RRF_RT_ANY, NULL, (PVOID)&value, &BufferSize);
                    printf("%s",value);
                    printf("\n");
                    strcpy(versions[i],achKey);

            }
            else
                continue;
        }
    }
}
            TCHAR* big=0;
        for(i=0;i<cSubKeys;i++)
        {

            if(strlen(versions[i])==8)
            {
                _tprintf(TEXT(" versions are %s:\n"),versions[i]);
                if(versions[i]>big)
                    big=versions[i];
            }
                else
                    continue;
        }
            _tprintf(" \nLatest version in the system is %s\n",big);
}
int _tmain(int argc, _TCHAR* argv[])
{
  HKEY hKey;
LONG dwRegOPenKey = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\JavaSoft\\Java Runtime Environment\\"), 0, KEY_READ, &hKey);
if(dwRegOPenKey == ERROR_SUCCESS)
{
    printf("RegOpenKeyEx succeeded, error code %d\n", GetLastError());
    QueryKey(hKey);

} 
else
{
    printf("RegOpenKeyEx failed, error code %d\n", dwRegOPenKey);
}
    RegCloseKey(hKey);
    return 0;
}

1 个答案:

答案 0 :(得分:3)

您没有检查RegGetValue的返回值,它会告诉您ERROR_INSUFFICIENT_BUFFER。一些调试会发现BufferSize变量越来越小。这是因为您在每次调用BufferSize之前都没有将sizeof(value)变量重置为RegGetValue,因此每次调用都会重复使用上次调用剩余的值,即值的大小检索。 Java 1.5的调用成功,因为它是第一次调用。它成功用于Java 1.6和1.7,因为这些值恰好与Java 1.5的值相同。最后,Java 1.8失败了,因为这个值比其他值长。

TL; DR :在致电BufferSize = sizeof(value);之前设置RegGetValue