c++检测JAVA环境

来源:互联网 发布:js trigger click 编辑:程序博客网 时间:2024/04/27 20:08

最近用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 123HKEY 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 NDEBUGILog log;#elseLog log;#endif // NDEBUGILog* 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;}



0 0
原创粉丝点击