Я использую NSIS и Launch4j, чтобы обернуть приложение Java Desktop. Так что мне нужно не только обнаружить какой-либо JRE, но и тот, который Launch4j найдет с его алгоритмом поиска. Единственный подход, который имеет смысл - это запустить короткую Java-программу в установщике NSIS. Вот Java:
public class DetectJVM {
private static final String keys [] = {
"sun.arch.data.model",
"com.ibm.vm.bitmode",
"os.arch",
};
public static void main (String [] args) {
boolean print = args.length > 0 && "-print".equals(args[0]);
for (String key : keys ) {
String property = System.getProperty(key);
if (print) System.out.println(key + "=" + property);
if (property != null) {
int errCode = (property.indexOf("64") >= 0) ? 64 : 32;
if (print) System.out.println("err code=" + errCode);
System.exit(errCode);
}
}
}
}
Оберните это с Launch4J. Используйте тип заголовка GUI, но также установите значение true. В противном случае код ошибки будет утерян. (Я включил все это в мой скрипт сборки Netbeans Ant.
Вот соответствующий код NSIS, который его использует:
File ... ; unpack files including detectjvm.exe.
ClearErrors
ExecWait '"$INSTDIR\detectjvm.exe"' $0
IfErrors DetectExecError
IntCmp $0 0 DetectError DetectError DoneDetect
DetectExecError:
StrCpy $0 "exec error"
DetectError:
MessageBox MB_OK "Could not determine JVM architecture ($0). Assuming 32-bit."
Goto NotX64
DoneDetect:
IntCmp $0 64 X64 NotX64 NotX64
X64:
File ... 64-bit AMD DLLs.
Goto DoneX64
NotX64:
File ... 32-bit x86 DLLs.
DoneX64:
Delete $INSTDIR\detectjvm.exe
Это прекрасно работает на очень большом количестве машин от WinXP без SP до Vista и Win7 со всеми SP, 32- и 64-разрядными.
Обратите внимание, что в моем сценарии NSIS я использую существующий пакет, который проверяет, установлена ли JVM, и делает ли это в первую очередь, поэтому 32-разрядный выбор по умолчанию будет происходить только в том случае, если что-то пошло не так с установкой JVM, в этом случае набор копируемых вами DLL-файлов в любом случае не будет иметь значения.
Надеюсь, это кому-нибудь пригодится.