web-dev-qa-db-ja.com

Javaを使用してWindowsの32または64ビットアーキテクチャをどのように決定しますか?

Javaを使用してWindowsの32または64ビットアーキテクチャをどのように決定しますか?

54
Matthew

_os.Arch_プロパティは、[〜#〜] jre [〜#〜]のアーキテクチャのみを提供し、基礎となるOS。

64ビットシステムに32ビットjreをインストールすると、System.getProperty("os.Arch")は_x86_を返します

基礎となるアーキテクチャを実際に決定するには、ネイティブコードを記述する必要があります。詳細については この投稿 を参照してください(およびサンプルネイティブコードへのリンク)。

54
James Van Huis

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では、AppleはOSに合わせてJVMをロックダウンします。ただし、LinuxやSolarisなど。64ビットシステムで32ビットJVMを使用する場合があります。慎重に使用してください。

74
Boolean

コマンドプロンプト(コマンド-> wmic OS get OSArchitecture)を使用して、OSアーキテクチャを取得しました。次のプログラムは、すべての必須パラメーターを取得するのに役立ちます。

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();

    }

}
5
Crusaderpyro

免責事項:これを重複した回答としてダウン票しないでください。これに対して、私はJavaコードソリューションはネイティブコードです)を共有したかったためです。

ジェームズ・ヴァン・ハウス氏の答えをまとめたいと思います。プロパティos.Arch:System.getProperty("os.Arch");はJREのビット数を返すため、これは実際には非常に便利です。記事から:

コードでは、まずIntPtrのサイズを確認する必要があります。8が返される場合、64ビットOSで実行しています。 4が返される場合、32ビットアプリケーションを実行しているので、ネイティブで実行しているか、WOW64で実行しているかを知る必要があります。

したがって、IntPtrサイズチェックは、「os.Arch」を見て実行するチェックと同じです。この後、プロセスがネイティブで実行されているか、WOW64で実行されているかを判断できます。

これは、必要なネイティブ関数の使用を提供するjnaライブラリ(たとえば NativeLibrary )を使用して実行できます。

//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

}

このようなものも動作する可能性がありますが、最初のバージョンはx64およびx64 OSの32ビットJREでテストしたものなので推奨します。また、以下では「IsWow64Process」関数が存在するかどうかを実際にチェックしないため、より安全な方法でなければなりません。

ここでは、JREチェックの例を追加します。見つけるのは難しくありませんが、完全なものになるようにします。

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);
}
2
wckan_

(Windowsのみ)C:\ Windows\SysWOW64が存在するかどうかを確認します。ディレクトリが存在する場合、64ビットプロセスです。それ以外の場合は、32ビットプロセスです。

1
Olligaming1107

たぶんそれは最善の方法ではありませんが、うまくいきます。

私がすることは、WindowsがProgram Files x86フォルダー用に構成した「環境変数」を取得することだけです。 Windows x64にはフォルダー(Program Files x86)があり、x86にはないという意味です。ユーザーはEnviroment VariablesのProgram Filesパスを変更できるか、C:\に「Program Files(x86)」というディレクトリを作成できるため、フォルダーの検出は使用せず、「Enviroment Path 「プログラムファイル(x86)」のWindowsレジストリの変数。

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);

    }

}
0
Blackgeo32

このコードを試すことができます。JVMのモデルを検出する方が良いと思います

boolean is64bit = System.getProperty("Sun.Arch.data.model").contains("64");
0
user2181778