安装与NSIS安装过程中,我需要检查哪些JRE(32位VS 64位)被安装在系统上。我已经知道我可以检查系统属性“sun.arch.data.model
”,但这是特定于Sun的。我想知道是否有一个标准的解决方案。如何检测安装哪种类型的JRE的 - 32位与64位
回答
在Linux上,我的(JAVA)VM报告java.vm.name =的HotSpot的Java(TM)64位服务器VM。对于系统的javadoc声明System.getProperty始终拥有该值,但都在sun.arch.data.model沉默。
不幸的是,他们没有指定的系统属性会这么一些其他JVM可能只是报告java.vm.name =埃德加什么。
BTW,通过“安装在系统上”,我假设你的意思是“当前正在运行的JVM”?
System.getProperty("os.arch");
的“操作系统”的部分似乎是有点用词不当,或者是原设计者没有想到的JVM到:
的JVM架构中使用可使用“os.arch”属性检索在没有写入的体系结构上运行。返回值似乎是inconsistent。
的NetBeans安装团队JVM的tackling the issue VS OS架构。报价:
64位:Java和系统
履带作为Issue 143434。
目前我们使用JVM的64位,以 确定系统(并且因此 Platform.getHardwareArch())是64位的 与否。这绝对是错误的,因为 有可能在64位系统上运行32位JVM上的 。在32位JVM上运行时,我们应该找到一个 解决方案来检查操作系统真正的64位 。
- 用于Windows它可以使用WindowsRegistry.IsWow64Process()
- 用于Linux做 - 通过检查 'UNAME -m/-p' == x86_64的
- 用于Solaris它可以使用例如进行“的isainfo -b”
- 为Mac OSX它不能使用UNAME参数来完成,或许可以通过 64位二进制 创建和平台上执行的解决... (不幸的是,这并不工作:( 我创建的二进制只有x86_64的 和PPC64拱,这是成功的老虎执行 ..)
- 的通用Unix的支持 - 目前尚不清楚,以及...可能检查 为同'uname -m/-p'/'getconf LONG_BIT'并将它与一些 可能的64位值(x86_64,x64, amd64,ia64)进行比较
0123从不同的JVM和
样品性能都在64位的Ubuntu 8.0上运行。4:
32位IBM 1.5:
java.vendor=IBM Corporation
java.vendor.url=http://www.ibm.com/
java.version=1.5.0
java.vm.info=J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20061001 (JIT enabled)
J9VM - 20060915_08260_lHdSMR
JIT - 20060908_1811_r8
GC - 20060906_AA
java.vm.name=IBM J9 VM
java.vm.specification.name=Java Virtual Machine Specification
java.vm.specification.vendor=Sun Microsystems Inc.
java.vm.specification.version=1.0
java.vm.vendor=IBM Corporation
java.vm.version=2.3
os.arch=x86
os.name=Linux
os.version=2.6.24-23-generic
sun.arch.data.model=32
64日1.6:
java.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi
java.version=1.6.0_05
java.vm.info=mixed mode
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vm.specification.name=Java Virtual Machine Specification
java.vm.specification.vendor=Sun Microsystems Inc.
java.vm.specification.version=1.0
java.vm.vendor=Sun Microsystems Inc.
java.vm.version=10.0-b19
os.arch=amd64
os.name=Linux
os.version=2.6.24-23-generic
sun.arch.data.model=64
64位GNU 1.5:
java.vendor=Free Software Foundation, Inc.
java.vendor.url=http://gcc.gnu.org/java/
java.version=1.5.0
java.vm.info=GNU libgcj 4.2.4 (Ubuntu 4.2.4-1ubuntu3)
java.vm.name=GNU libgcj
java.vm.specification.name=Java(tm) Virtual Machine Specification
java.vm.specification.vendor=Sun Microsystems Inc.
java.vm.specification.version=1.0
java.vm.vendor=Free Software Foundation, Inc.
java.vm.version=4.2.4 (Ubuntu 4.2.4-1ubuntu3)
os.arch=x86_64
os.name=Linux
os.version=2.6.24-23-generic
(GNU版本不报告“的太阳。 arch.data.model“属性;推测其他JVM也不会)
系统上可能有32位和64位的JVM,并且其中有很多。
如果你已经有每个受支持的平台的DLL - 考虑制作一个小的可执行文件链接和运行,以便测试平台是否支持给定的功能。如果可执行文件链接并运行,则可以安装相应的共享库。
下面的代码检查machineType字段中可执行任何窗口以确定它是否是32或64位:
public class ExeDetect
{
public static void main(String[] args) throws Exception {
File x64 = new File("C:/Program Files/Java/jre1.6.0_04/bin/java.exe");
File x86 = new File("C:/Program Files (x86)/Java/jre1.6.0/bin/java.exe");
System.out.println(is64Bit(x64));
System.out.println(is64Bit(x86));
}
public static boolean is64Bit(File exe) throws IOException {
InputStream is = new FileInputStream(exe);
int magic = is.read() | is.read() << 8;
if(magic != 0x5A4D)
throw new IOException("Invalid Exe");
for(int i = 0; i < 58; i++) is.read(); // skip until pe offset
int address = is.read() | is.read() << 8 |
is.read() << 16 | is.read() << 24;
for(int i = 0; i < address - 60; i++) is.read(); // skip until pe header+4
int machineType = is.read() | is.read() << 8;
return machineType == 0x8664;
}
}
注意,代码已被压缩为简洁...
import sun.misc.*;
import java.lang.reflect.*;
public class UnsafeTest {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
System.out.println(unsafe.addressSize());
}
}
我正在使用NSIS和Launch4j来包装Java桌面应用程序。所以我不仅需要检测任何JRE,而且Launch4j会使用它的搜索算法。唯一有意义的方法是在NSIS安装程序中运行一个简短的Java程序。这里是在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
这已通过Vista中运行良好的一个非常大的品种从WinXP的机器,没有SP和Win7与32位和64位的所有SP
请注意,在我的NSIS脚本中,我正在使用现有软件包检查JVM是否已安装,并首先执行该操作,因此默认的32位只有在JVM安装出错的情况下才会发生选择,在这种情况下,您复制的DLL集合无论如何都不会影响
希望这对某人有帮助。
这是一个非常有用的解决方法。问题是,如果用户的64位机器没有与JVM一起安装?剧本将做出错误的假设。 – 2011-11-04 05:25:00
请注意,对于我的情况,我需要使用Launch4J将其添加到控制台。 – 2011-11-28 01:51:00
在编写Java代码时,我该如何区分32位和64位操作?
http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_detection
有没有公共API,可以让你32和 64位操作进行区分。把64位看作只是编写一次的另一个平台,可以在任何地方运行。但是,如果您想编写特定于平台的代码(对您不利),则系统属性 sun.arch.data.model的值为“32”,“64”或“unknown”。
正如ThorbjørnRavn Andersen在另一篇文章中所说的,32位JVM在64位操作系统上运行良好。如果您担心JVM位宽而不是操作系统位宽(假设您正在热点JVM上运行......),请使用sun.arch.data.model属性 – billsimons 2011-01-15 03:49:08
位问题不是因为的Java代码本身,但由于封装,我们的软件附带。假设如下:如果客户尝试安装我们的64位软件版本,但他只安装了32位Java;他被告知... – user97629 2011-01-24 10:29:32
如果您有要检查的.exe路径,可以使用this answer。基本上它只是查看.exe文件中的标题,并告诉你它是否在Windows上是64位或32位。
彼得·史密斯的答案是相同的逻辑,但做对 – Massimo 2017-07-02 18:27:23
java -version
对于一个64位的Java版本,它会打印:
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) ***64-Bit*** Server VM (build 25.92-b14, mixed mode)
对于32位,它会只是
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) Client VM (build 25.92-b14, mixed mode)
您可以尝试在命令行上: java的-d64 -version 如果它不是一个64位版本,你会得到一个消息如下所示: 此Java实例不支持64位JVM。请安装所需的版本。 查阅JVM的帮助选项以获取更多信息java -help – Massimo 2017-07-02 18:31:17
- 1. 如何检测VC++代码中的JRE位(32位或64位)
- 2. 如何检查我的Perl安装是32位还是64位?
- 3. 如何检查安装的wxPython是32位还是64位?
- 4. 如何检查安装的Anaconda是32位还是64位?
- 5. JNA调用与32位JRE但不与64位JRE
- 6. 在32位浏览器中检测64位jre?
- 7. 安装Pygame - 32位和64位
- 8. 32位和64位安装项目
- 9. windows 7 64位安装32位流星
- 10. 安装了32位安装的Python,显示为64位
- 11. Java和Eclipse - 32与64位
- 12. SHGetFolderPath()32位与64位
- 13. 如何检测Flex中的32位或64位操作系统?
- 14. 如何创建测试32位和64位Windows的安装程序条件
- 15. 检查solaris Sparc上JRE的安装版本是否为64位
- 16. 如何在64位JRE中运行32位JAVA Applet MOC XOS
- 17. 如何检测,如果CPU是32位还是64位
- 18. 32位和64位CPU/OS
- 19. 让qmake与32位和64位并行安装一起工作
- 20. 如何安装Python 2.7.3 32位和64位Windows上并排
- 21. 如何在32位PC上创建64位InstallShield安装程序?
- 22. 如何在64位PHP安装中使用32位整数?
- 23. 如何在Red Hat Linux 64位上安装python 32位
- 24. 使用C#检测本地SQL Server安装(32位以及64位)
- 25. 32与64位GC
- 26. Macintosh Python:64位与32位问题
- 27. 是否可以在bash脚本中检测32位与64位?
- 28. 如何以编程方式检测64位或32位机器?
- 29. 如何检测Cocoa应用程序是32位还是64位?
- 30. MySQL的ODBC 32与64位
注意,代码尽快打破在用户没有按不使用非常相同的版本... – 2009-12-03 15:00:19
-1可怕的方法。没有跨平台。硬编码版本。 – Tomas 2011-03-31 13:56:59
这是在Windows上检测64位可执行文件的通用方法。没有特定的jre版本。 – 2011-04-23 01:31:56