您的位置:首页 > 编程语言 > C语言/C++

c++检测JAVA环境

2016-04-17 16:39 603 查看
最近用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 <Windows.h>

// 安全的取得真实系统信息
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: