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

在windows上从C中检测32/64位Java,java,c,windows,Java,C,Windows,我想知道安装在用户机器上的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运行时是否支持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位程序,则只会检测到64位java

通过合理的可靠性,您可以检查%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版本

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");
    }
}
我的建议是首先解析PATH环境变量,并找到java的第一个目标。第二步是查看java.exe文件的COFF头。 使用该功能,您可以查询NT标头,其中包含字段FileHeader,这是一个

下面是一些关于如何实现此功能的示例:

希望这对您有所帮助。

干杯

只有在Solaris上才可以使用
-d32
-d64
选项。在Windows上使用Oracle Java时,它们对我来说很好。这并不能回答问题。Java 64和32可能都已安装,这仅检测您调用的任何Java的体系结构。我特别想知道Java在用C编写的windows 32应用程序中支持哪些体系结构。您可以运行安装的任何版本。您必须找到/知道它们安装在哪里,但一旦找到,您就需要确定它们的位置。我能补充什么?显然不能。问题中的代码只能以与编译的C代码相同的位运行java。您能否确认您可以从该应用程序运行64位C程序?这在Java代码中似乎不是问题。感谢您的回复。这看起来很有希望。你知道这种方法有多“合理可靠”吗?这些位置是否总是出现在Oracle Java安装中?我个人认为它很健壮。Oracle将可执行文件放在这些目录中。您可以在任何地方调用java,而不会影响您的机器路径。@java可以安装在您系统的任何地方。