在Windows上从C中检测32/64位Java

我想知道在用户计算机上安装的Java运行时是否支持32位和64位,而且我想从C中执行此操作。我曾经想过,像下面这样的事情可以做到这一点:

检测64位的java:

int f=0 char *path = (char*) malloc(32768); char out[1035]; FILE *fp; if(f) fprintf(f,"Checking if 64-bit Java is available via the java command\n"); java64ok = 1; strcpy(path,"java -d64 -version 2>&1"); fp = _popen(path, "r"); if (fp == NULL) { if(f) fprintf(f,"Failed to run command\n" ); } if(fgets(out, sizeof(out), fp) != NULL){ if(strncmp(out,"Error",5)==0){ java64ok = 0; } while (fgets(out, sizeof(out), fp) != NULL) {} } if (feof(fp)){ pclose( fp ); } else{ if(f) fprintf(f, "Error: Failed to read the pipe to the end.\n"); } 

检测32位Java:

 if(f) fprintf(f,"Checking if 32-bit Java is available via the java command\n"); java32ok = 1; strcpy(path,"java -d32 -version 2>&1"); fp = _popen(path, "r"); if (fp == NULL) { if(f) fprintf(f,"Failed to run command\n" ); } if(fgets(out, sizeof(out), fp) != NULL){ if(strncmp(out,"Error",5)==0){ java32ok = 0; } while (fgets(out, sizeof(out), fp) != NULL) {} } if (feof(fp)){ pclose( fp ); } else{ if(f) fprintf(f, "Error: Failed to read the pipe to the end.\n"); } 

不幸的是,如果用户正在运行一个64位系统,那么如果C代码被编译为一个32位可执行文件,那么只检测到32位Java,如果程序被编译为64位程序。

具有合理的可靠性,您可以检查%SYSTEMROOT%\ SysWOW64 \ java.exe(这是32位java.exe驻留在64位计算机上)和%SYSTEMROOT%\ System32 \ java.exe(这是64位Java驻留在一个64位的机器上,而32位的java驻留在一个32位的机器上。)

使用Windows API函数GetEnvironmentVariable可以推导出%SYSTEMROOT%,或者开始时,将硬编码转换为“C:\ Windows”,根据需要转义\。

如何从外部检测版本取决于平台。 我建议你运行一个简短的Java程序来告诉你。

 public class Bitness { public static void main(String... ignored) { System.out.println(is64Bit() ? "64" : "32"); } private static boolean is64Bit0() { String systemProp; systemProp = System.getProperty("com.ibm.vm.bitmode"); if (systemProp != null) { return "64".equals(systemProp); } systemProp = System.getProperty("sun.arch.data.model"); if (systemProp != null) { return "64".equals(systemProp); } systemProp = System.getProperty("java.vm.version"); return systemProp != null && systemProp.contains("_64"); } } 

这样你可以运行java -cp {whatever} Bitness ,它会告诉你。

Bathsheba的建议是相当稳固的,不过取决于在系统上如何定义PATH变量,可能在%SYSTEMROOT%\之前找到另一个java.exe二进制文件,所以有可能是不同的java版本用过的。

我的建议是首先解析PATH环境变量,并找到java的第一个命中。 第二步是查看java.exe文件的COFF头。 使用ImageNtHeader函数,您可以查询NT标题,并且它包含字段FileHeader ,它是一个IMAGE_FILE_HEADER 。

这里有一些关于如何实现这个的例子:
https://stackoverflow.com/a/4316804/435583

希望这可以帮助你。
干杯