2015-09-08 120 views
0

我正在寫一個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路徑的長度時,即使輸出1.8版本的路徑爲1.7,它也顯示正確的長度爲36(因爲它應該是JAVA 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; 
} 
+1

你不檢查'RegGetValue'的返回值。它由於緩衝區不足而失敗,因爲您在最後一個參數中傳遞了錯誤的緩衝區大小。瀏覽你的代碼,看看發生了什麼。 –

+0

你分配了多少TCHAR指針。您的變量'版本'陰影全局變量。 'javapath'永遠不會被分配。爲什麼'BufferSize'是全局的?你可以通過傳遞一個struct的引用來避免全局變量嗎?誰控制'版本'中的指針的生命週期? – user877329

+0

如果是Bufferoverflow的問題,那麼爲什麼即使我安裝了java 1.5或1.6或1.7的其他更新,它們都顯示正確的路徑?無論安裝了多少版本,只有在版本1.8時才顯示系統中安裝的以前版本的路徑。 @RaymondChen – TheEvilGuardian

回答

3

你是不是檢查RegGetValue的返回值,這將告訴你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);