RegGetValue() returns 错误信息
RegGetValue() returns wrong information
我正在编写一个 VC++ 程序,它应该 return Java 版本以及注册表中的 Java 主页。该代码的目的是显示单个系统中安装的所有 JRE 版本,并显示最高版本。我的系统中安装了 JRE 1.5、1.6、1.7 和 1.8。我在显示有关版本的信息时没有问题。但是当从注册表显示 JavaHome 时,路径仅适用于 Java 版本 1.5、1.6 和 1.7。对于 1.8 版,它显示 JRE 7 的路径。我尝试使用 INSTALLDIR 从安装的每个 JRE 中存在的 MSI 目录显示路径。然后,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;
}
您没有检查 RegGetValue
的 return 值,这会告诉您 ERROR_INSUFFICIENT_BUFFER
。一些调试会发现 BufferSize
变量越来越小。那是因为你没有在每次调用 RegGetValue
之前将 BufferSize
变量重置为 sizeof(value)
,所以每次调用都会重用上一次调用留下的值,即值的大小检索。 Java 1.5 的调用成功,因为这是第一次调用。它对 Java 1.6 和 1.7 成功,因为这些值的长度恰好与 Java 1.5 的值相同。最后,Java 1.8 失败,因为该值比其他值长。
TL;DR: 在调用RegGetValue
.
之前设置BufferSize = sizeof(value);
我正在编写一个 VC++ 程序,它应该 return Java 版本以及注册表中的 Java 主页。该代码的目的是显示单个系统中安装的所有 JRE 版本,并显示最高版本。我的系统中安装了 JRE 1.5、1.6、1.7 和 1.8。我在显示有关版本的信息时没有问题。但是当从注册表显示 JavaHome 时,路径仅适用于 Java 版本 1.5、1.6 和 1.7。对于 1.8 版,它显示 JRE 7 的路径。我尝试使用 INSTALLDIR 从安装的每个 JRE 中存在的 MSI 目录显示路径。然后,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;
}
您没有检查 RegGetValue
的 return 值,这会告诉您 ERROR_INSUFFICIENT_BUFFER
。一些调试会发现 BufferSize
变量越来越小。那是因为你没有在每次调用 RegGetValue
之前将 BufferSize
变量重置为 sizeof(value)
,所以每次调用都会重用上一次调用留下的值,即值的大小检索。 Java 1.5 的调用成功,因为这是第一次调用。它对 Java 1.6 和 1.7 成功,因为这些值的长度恰好与 Java 1.5 的值相同。最后,Java 1.8 失败,因为该值比其他值长。
TL;DR: 在调用RegGetValue
.
BufferSize = sizeof(value);