Reputation: 17348
I would like to find out if the Java runtime installed on a user's machine supports 32 and 64-bit, and I would like to do this from within C. I had thought that something like the following would do the trick:
Detect 64-bit 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");
}
Detect 32-bit 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");
}
Unfortunately, this appears that if the user is running a 64-bit system only the 32 bit java is detected if the C code is compiled as a 32 bit executable, and only the 64-bit Java is detected if the program is compiled as a 64-bit program.
Upvotes: 1
Views: 163
Reputation: 2317
the suggestion of Bathsheba is quite solid, though depending on how the PATH variable is defined on a system, it might be possible that another java.exe binary is found before %SYSTEMROOT%\, so there is a chance that a different java version is used.
My suggestion would be to first parse PATH environment variable and find the first hit for java. Second step would be to look at the COFF header of the java.exe file. With the ImageNtHeader function, you can query the NT header and this contains the field FileHeader, which is a IMAGE_FILE_HEADER.
Here's some example on how you would implement this:
https://stackoverflow.com/a/4316804/435583
Hope this helps you out.
Cheers
Upvotes: 0
Reputation: 533530
How you detect the version externally is platform dependant. I sugges you run a short Java program to tell you.
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");
}
}
This way you can run java -cp {whatever} Bitness
and it will tell you.
Upvotes: 0
Reputation: 234715
With reasonable reliability, you can check %SYSTEMROOT%\SysWOW64\java.exe (which is where 32 bit java.exe resides on a 64 bit machine), and %SYSTEMROOT%\System32\java.exe (which is where 64 bit java resides on a 64 bit machine and also where 32 bit java resides on a 32 bit machine.)
Use the Windows API function GetEnvironmentVariable to deduce %SYSTEMROOT%, or, to get started, hardcode to "C:\Windows", escaping \ as necessary.
Upvotes: 2