c++检测JAVA环境

最近用JAVA的SWING框架写了一个小工具,但由于JAVA在使用前想检查一下用户是否安装了JAVA虚拟机。

于是用MFC来完成检测的工作,然后调用JAVA.exe来启动工具。


在网上找了一些方案,感觉比较靠谱的是从注册表中的获取JAVA安装路径,然后检查这个路径是否存在。

(这年头GOOGLE被墙,程序也只会百度了,如果百度没了,怎么办?)

其间碰到两个比较蛋疼的事情:

1、在32位系统上运行正常,在64位上使用RegOpenKeyEx()出错。他会返回一个错误码,现在记不清了。

查了一下原来第4个参数REGSAM出了问题。


REGSAM regsam = KEY_QUERY_VALUE ;

这样能在32位系统上运行。


REGSAM regsam = KEY_QUERY_VALUE | KEY_WOW64_64KEY;

这样才能在64位系统上运行。


后来问题就这样解决了,虽知其然,但不知其所以然,比较悲惧,下次碰到估计又要跪。


2、一直以为jvm.dll就是放在%java_home%/bin/client/目录中,尼马,装完JDK1.8, JDK1.7,  JDK1.6后神奇的发现%java_home%/bin/server/中也会有jvm.dll存在,具体看你的JAVA或JRE版本,那么多版本,不知道用户会装哪个版本啊。没法,只能找完%java_home%/bin/clinet/目录,再找%java_home%/bin/server/目录。找到了就算有JAVA环境吧。方法比较笨,问题算解决了。不知道有没有高人指点,有更科学的办法。后找了一下,发现JAVA虚拟机的创建会分很多版本,还有一个文件(jvm.cfg)控制。具体创建哪个JAVA虚拟机就看这个文件了。再深入的研究就没有尝试了。

最后贴上相关代码,方便大家一起交流:

#include "stdafx.h"
#include "JavaEnv.h"
#include "Log.h"
#include 

// 安全的取得真实系统信息
VOID SafeGetNativeSystemInfo(__out LPSYSTEM_INFO lpSystemInfo)
{
	if (NULL == lpSystemInfo)    return;
	typedef VOID(WINAPI *LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
	LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle("kernel32"), "GetNativeSystemInfo");;
	if (NULL != fnGetNativeSystemInfo)
	{
		fnGetNativeSystemInfo(lpSystemInfo);
	}
	else
	{
		GetSystemInfo(lpSystemInfo);
	}
}


// 获取操作系统位数
int GetSystemBits()
{
	SYSTEM_INFO si;
	SafeGetNativeSystemInfo(&si);
	if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
		si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
	{
		return 64;
	}
	return 32;
}

char* GetJreHome(int BIT, REGSAM regsam)
{
#define MYBUFF 123
	HKEY hKey;
	long lRet;
	CHAR* dir = new CHAR[MYBUFF];
	DWORD dwBufLen = MYBUFF;
	CHAR* s = new CHAR[MYBUFF];
	if (BIT == 64)
	{
		strncpy_s(s, MYBUFF, "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Runtime Environment\\", MYBUFF);
	}
	else
	{
		strncpy_s(s, MYBUFF, "SOFTWARE\\JavaSoft\\Java Runtime Environment\\", MYBUFF);
	}
	lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, s, 0, regsam, &hKey);

	if (lRet != ERROR_SUCCESS)
		return NULL;
	lRet = RegQueryValueEx(hKey, "CurrentVersion", NULL, NULL, (LPBYTE)dir, &dwBufLen);
	RegCloseKey(hKey);

	if (lRet != ERROR_SUCCESS)
		return NULL;
	strcat_s(s, MYBUFF, dir);

	lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, s, 0, regsam, &hKey);

	if (lRet != ERROR_SUCCESS)
		return NULL;
	dwBufLen = MYBUFF;
	lRet = RegQueryValueEx(hKey, "JavaHome", NULL, NULL, (LPBYTE)dir, &dwBufLen);
	RegCloseKey(hKey);
	delete s;

	if (lRet != ERROR_SUCCESS)
		return NULL;
	return dir;
}


const char* JavaEnv::getJvmPath()
{
	const static int PATH_LEN = 512;
	static char PATH_JVM[PATH_LEN] = { 0 };
	if (PATH_JVM[0] != 0)
	{
		return PATH_JVM;
	}

#ifdef NDEBUG
	ILog log;
#else
	Log log;
#endif // NDEBUG
	ILog* pLog = &log;

	int bit = GetSystemBits();
	REGSAM regsam = KEY_QUERY_VALUE;
	if (bit == 64)
	{
		regsam |= KEY_WOW64_64KEY;
	}

	const char* path = GetJreHome(32, regsam);
	if (path == NULL)
	{
		path = GetJreHome(64, regsam);
		if (path == NULL)
		{
			return PATH_JVM;
		}
	}
	const static const char* DIR_JVM[2];
	DIR_JVM[0] = "bin\\client\\jvm.dll";
	DIR_JVM[1] = "bin\\server\\jvm.dll";
	for (int i = 0; i < 2; i++)
	{
		int len = strlen(path);
		char ch = path[len - 1];
		if (ch == '\\' || ch == '/')
		{
			sprintf_s(PATH_JVM, "%s%s", path, DIR_JVM[i]);
		}
		else
		{
			sprintf_s(PATH_JVM, "%s\\%s", path, DIR_JVM[i]);
		}
		fstream file;
		file.open(PATH_JVM, ios::in);
		if (!file)
		{
			PATH_JVM[0] = 0;
		}
		else
		{
			file.close();
			break;
		}
	}
	return PATH_JVM;
}



你可能感兴趣的:(mfc)