我正在编写一个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;
}
答案 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
。