Delphi source, pure Win32 API:
/// <summary>
/// Enumerates all installed Common Language Runtime Engines.
/// </summary>
/// <param name="Index">Zero-based index of looked runtime record.</param>
/// <returns>True if runtime with specified index found.</returns>
function EnumInstalledRuntimes(Index: Integer; out VersionName: String): Boolean;
var
hkey: Windows.HKEY;
hsubkey: Windows.HKEY;
I: Cardinal;
J: Cardinal;
NameBuf: array[0..MAX_PATH] of Char;
CNameBuf: Cardinal;
lwt: TFileTime;
vt: DWORD;
AnyFound: Boolean;
begin
Result := False;
VersionName := '';
if ERROR_SUCCESS = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar('SOFTWARE\Microsoft\.NETFramework\policy'), 0, KEY_ENUMERATE_SUB_KEYS, hkey) then
try
I := 0;
while True do
begin
AnyFound := False;
CNameBuf := MAX_PATH + 1;
if ERROR_SUCCESS <> RegEnumKeyEx(hkey, I, @NameBuf[0], CNameBuf, nil, nil, nil, @lwt) then
begin
Break;
end;
if (NameBuf[0] = 'v') and (NameBuf[1] in ['1'..'9']) then
begin
VersionName := String(NameBuf);
if ERROR_SUCCESS = RegOpenKeyEx(hkey, @NameBuf[0], 0, KEY_QUERY_VALUE, hsubkey) then
try
J := 0;
while true do
begin
CNameBuf := MAX_PATH + 1;
if ERROR_SUCCESS <> RegEnumValue(hsubkey, J, @NameBuf[0], CNameBuf, nil, @vt, nil, nil) then
begin
Break;
end;
if (vt = REG_SZ) and (NameBuf[0] <> #0) then
begin
VersionName := VersionName + '.' + String(NameBuf);
AnyFound := True;
Break;
end;
Inc(J);
end;
finally
RegCloseKey(hsubkey);
end;
end;
Inc(I);
if AnyFound then
begin
if Index = 0 then
begin
Result := True;
Break;
end;
Dec(Index);
end;
end;
finally
RegCloseKey(hkey);
end;
end;
По просьбам людей по переписке вот вариант на C++.
Внимание — используются классы и макросы ATL:
// netv.cpp : Implementation of WinMain
#include "stdafx.h"
#include "resource.h"
// The module attribute causes WinMain to be automatically implemented for you
[ module(EXE, uuid = "{54634DD0-6A8F-4681-ACB9-B39A05352ED8}",
name = "netv",
helpstring = "netv 1.0 Type Library",
resource_name = "IDR_NETV") ];
/// <summary>
/// Enumerates all installed Common Language Runtime Engines.
/// </summary>
/// <param name="Index">Zero-based index of looked runtime record.</param>
/// <param name="VersionName">Version name in form vx.x.xxxx.</param>
/// <returns>S_OK if runtime with specified index found else S_FALSE.</returns>
HRESULT EnumInstalledRuntimes(int Index, BSTR * pVersionName)
{
const size_t CNAMEBUF = MAX_PATH + 1;
HKEY hKey;
CComBSTR versionName;
ATLASSERT(pVersionName != NULL);
HRESULT hr = S_FALSE;
if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\.NETFramework\\policy"), 0, KEY_ENUMERATE_SUB_KEYS, &hKey))
{
for(unsigned i = 0;;)
{
bool anyFound = false;
DWORD cNameBuf = CNAMEBUF;
TCHAR nameBuf[CNAMEBUF];
FILETIME lwt;
if(ERROR_SUCCESS != RegEnumKeyEx(hKey, i, nameBuf, &cNameBuf, NULL, NULL, NULL, &lwt))
{
break;
}
if((nameBuf[0] == _TCHAR('v')) && _istdigit(nameBuf[1]))
{
HKEY hSubKey;
versionName.Empty();
versionName.Append(nameBuf);
if(ERROR_SUCCESS == RegOpenKeyEx(hKey, nameBuf, 0, KEY_QUERY_VALUE, &hSubKey))
{
for(unsigned j = 0;; j++)
{
DWORD vt;
cNameBuf = CNAMEBUF;
if(ERROR_SUCCESS != RegEnumValue(hSubKey, j, nameBuf, &cNameBuf, NULL, &vt, NULL, NULL))
{
break;
}
if((vt == REG_SZ) && (nameBuf[0] != _TCHAR('\0')))
{
versionName.Append(_TCHAR('.'));
versionName.Append(nameBuf);
anyFound = true;
break;
}
} // for(unsigned j
RegCloseKey(hSubKey);
} // if(ERROR_SUCCESS == RegOpenKeyEx
}
i++;
if(anyFound)
{
if(Index == 0)
{
hr = S_OK;
break;
}
Index--;
} // if(anyFound)
} // for(unsigned i
RegCloseKey(hKey);
} // if(ERROR_SUCCESS == RegOpenKeyEx
versionName.CopyTo(pVersionName);
return hr;
}
void main()
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
for(int i = 0;; i++)
{
DWORD written;
CComBSTR vn;
if(S_FALSE == EnumInstalledRuntimes(i, &vn))
{
break;
}
CW2CT szMyString(vn);
WriteConsole(hStdOut, szMyString, vn.Length(), &written, NULL);
WriteConsole(hStdOut, _T("\r\n"), 2, &written, NULL);
}
}
Здравствуйте, Akzhan, Вы писали хороший код...
А вот можно то же самое но про Java?
(Три смысловых слоя)
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, Akzhan, Вы писали хороший код...
Не особо хороший. По идее тут правильнее использовать идиому FindFirst/FindNext/FindClose. Просто лень было делать.
CS>А вот можно то же самое но про Java?
А я не знаю, как на Java к Win32/Win64 Registry обращаться
Да и IDE качать/ставить не хочется — больно большие (что Sun OneStudio, что Eclipse, что IntelliJ IDEA trial, что JBuilder).
CS>(Три смысловых слоя)