Я пишу программу 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. Я попытался отобразить путь, используя INSTALLDIR из каталога MSI, присутствующего в каждой установленной JRE. Тогда также есть проблема с 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.7 для версии 1.8. Это что-то не так со сравнением строк? Помогите мне в этом, пожалуйста.RegGetValue() возвращает неверную информацию
#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;
}
Вы не проверяете возвращаемое значение 'RegGetValue'. Он не работает из-за недостаточного буфера, потому что вы пропускаете неправильный размер буфера в последнем параметре. Пройдите через свой код, чтобы узнать, что происходит. –
Сколько указателей TCHAR вы выделяете. Ваша переменная 'version' изменяет глобальную переменную. 'javapath' никогда не назначается. Почему «BufferSize» глобальный? Можете ли вы избежать глобальных переменных, передав вместо этого ссылку на структуру? Кто контролирует время жизни указателей в «версиях»? – user877329
Если это проблема с Bufferoverflow, то почему, даже если я устанавливаю другие обновления java 1.5 или 1.6 или 1.7, все они показывают правильный путь? Независимо от того, сколько версий установлено, только когда дело доходит до версии 1.8, он показывает путь к предыдущей версии, установленной в системе. @RaymondChen – TheEvilGuardian