Program Tip

Java를 사용하여 Windows의 32 비트 또는 64 비트 아키텍처를 어떻게 결정합니까?

programtip 2021. 1. 10. 19:29
반응형

Java를 사용하여 Windows의 32 비트 또는 64 비트 아키텍처를 어떻게 결정합니까?


Java를 사용하여 Windows의 32 비트 또는 64 비트 아키텍처를 어떻게 결정합니까?


os.arch속성은 기본 OS가 아닌 JRE 의 아키텍처 만 제공합니다 .

64 비트 시스템에 32 비트 jre를 설치하면 다음 System.getProperty("os.arch")이 반환됩니다.x86

실제로 기본 아키텍처를 결정하려면 네이티브 코드를 작성해야합니다. 자세한 정보 (및 샘플 네이티브 코드 링크)는 이 게시물참조하세요.


나는 os.arch 시스템 변수를 읽는 것을 정확히 신뢰하지 않습니다. 사용자가 64 비트 시스템에서 64 비트 JVM을 실행하는 경우 작동합니다. 사용자가 64 비트 시스템에서 32 비트 JVM을 실행하는 경우 작동하지 않습니다.

다음 코드는 Windows 64 비트 운영 체제를 올바르게 감지하는 데 사용됩니다. Windows 64 비트 시스템에서는 "Programfiles (x86)"환경 변수가 설정됩니다. 32 비트 시스템에서는 설정되지 않으며 java는 null로 읽습니다.

boolean is64bit = false;
if (System.getProperty("os.name").contains("Windows")) {
    is64bit = (System.getenv("ProgramFiles(x86)") != null);
} else {
    is64bit = (System.getProperty("os.arch").indexOf("64") != -1);
}

Linux, Solaris 또는 Mac과 같은 다른 운영 체제의 경우에도이 문제가 발생할 수 있습니다. 따라서 이것은 완전한 솔루션이 아닙니다. Mac의 경우 사과가 OS와 일치하도록 JVM을 잠그기 때문에 안전 할 수 있습니다. 그러나 Linux 및 Solaris 등은 64 비트 시스템에서 32 비트 JVM을 계속 사용할 수 있습니다. 따라서주의해서 사용하십시오.


OS 아키텍처를 얻기 위해 명령 프롬프트 (command-> wmic OS get OSArchitecture)를 사용했습니다. 다음 프로그램은 필요한 모든 매개 변수를 가져 오는 데 도움이됩니다.

import java.io.*;

public class User {
    public static void main(String[] args) throws Exception {

        System.out.println("OS --> "+System.getProperty("os.name"));   //OS Name such as Windows/Linux

        System.out.println("JRE Architecture --> "+System.getProperty("sun.arch.data.model")+" bit.");       // JRE architecture i.e 64 bit or 32 bit JRE

        ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c","wmic OS get OSArchitecture");
        builder.redirectErrorStream(true);
        Process p = builder.start();
        String result = getStringFromInputStream(p.getInputStream());

        if(result.contains("64"))
            System.out.println("OS Architecture --> is 64 bit");  //The OS Architecture
        else
            System.out.println("OS Architecture --> is 32 bit");

        }


    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }

}

면책 조항 : Java 코드 솔루션을 이것에 공유하고 싶었으므로 중복 답변으로 찬성하지 마십시오 (모두 네이티브 코드입니다).

Mr. James Van Huis의 답변을 추가하고 싶습니다. os.arch : 속성 System.getProperty("os.arch");은 JRE의 비트를 반환하므로 실제로 매우 유용 할 수 있습니다. 기사에서 :

코드에서 먼저 IntPtr의 크기를 확인해야합니다. 8을 반환하면 64 비트 OS에서 실행중인 것입니다. 4를 반환하면 32 비트 응용 프로그램을 실행하는 것이므로 이제 기본적으로 실행 중인지 WOW64에서 실행 중인지 알아야합니다.

따라서 IntPtr 크기 검사는 "os.arch"를보고 수행하는 검사와 동일합니다. 그런 다음 프로세스가 기본적으로 실행 중인지 WOW64에서 실행 중인지 알아낼 수 있습니다.

This can be done using the jna library(e.g. NativeLibrary) which offers use of the native functions you need.

//test the JRE here by checking the os.arch property
//go into the try block if JRE is 32bit
try {
    NativeLibrary kernel32Library = NativeLibrary.getInstance("kernel32");
    Function isWow64Function = kernel32Library.getFunction("IsWow64Process");

    WinNT.HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess();
    IntByReference isWow64 = new IntByReference(0);
    Boolean returnType = false;
    Object[] inArgs = {
        hProcess,
        isWow64
    };
    if ((Boolean) isWow64Function.invoke(returnType.getClass(), inArgs))    {
        if (isWow64.getValue() == 1)    {
                //32bit JRE on x64OS
        }
    }
} catch (UnsatisfiedLinkError e) {  //thrown by getFunction

}

Something like this might also work, but I would recommend the first version, since it's the one I tested on x64 and 32bit JRE on x64 OS. Also it should be the safer way, because in the following you don't actually check whether or not the "IsWow64Process" function exists.

Here I am adding an example of the JRE check, just so it is complete, even though it's not hard to find.

Map<String, Integer> archMap = new HashMap<String, Integer>();
archMap.put("x86", 32);
archMap.put("i386", 32);
archMap.put("i486", 32);
archMap.put("i586", 32);
archMap.put("i686", 32);
archMap.put("x86_64", 64);
archMap.put("amd64", 64);
//archMap.put("powerpc", 3);
this.arch = archMap.get(SystemUtils.OS_ARCH);
if (this.arch == null)  {
    throw new IllegalArgumentException("Unknown architecture " + SystemUtils.OS_ARCH);
}

(Only for Windows) Check if C:\Windows\SysWOW64 exists. if the directory exist, it is a 64 bit process. Else, it is a 32 bit process.


You can try this code, I thinks it's better to detect the model of JVM

boolean is64bit = System.getProperty("sun.arch.data.model").contains("64");

Maybe it 's not the best way, but it works.

All I do is get the "Enviroment Variable" which windows has configured for Program Files x86 folder. I mean Windows x64 have the folder (Program Files x86) and the x86 does not. Because a user can change the Program Files path in Enviroment Variables, or he/she may make a directory "Program Files (x86)" in C:\, I will not use the detection of the folder but the "Enviroment Path" of "Program Files (x86)" with the variable in windows registry.

public class getSystemInfo {

    static void suckOsInfo(){

    // Get OS Name (Like: Windows 7, Windows 8, Windows XP, etc.)
    String osVersion = System.getProperty("os.name");
    System.out.print(osVersion);

    String pFilesX86 = System.getenv("ProgramFiles(X86)");
    if (pFilesX86 !=(null)){
        // Put here the code to execute when Windows x64 are Detected
    System.out.println(" 64bit");
    }
    else{
        // Put here the code to execute when Windows x32 are Detected
    System.out.println(" 32bit");
    }

    System.out.println("Now getSystemInfo class will EXIT");
    System.exit(0);

    }

}

System.getProperty("os.arch");

You can use the os.arch property in system properties to find out.

Properties pr = System.getProperties();
System.out.println(pr.getProperty("os.arch"));

If you are on 32 bit, it should show i386 or something

ReferenceURL : https://stackoverflow.com/questions/1856565/how-do-you-determine-32-or-64-bit-architecture-of-windows-using-java

반응형