Java で一意のコンピュータ識別子 (ディスク ID やマザーボード ID など) を取得するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1986732

  •  22-09-2019
  •  | 
  •  

質問

Windows、MacOS、そして可能であれば Linux 上で Java を搭載したコンピュータに固有の ID を取得したいと考えています。それはディスク UUID、マザーボード S/N である可能性があります...

Runtime.getRuntime().exec 使用できます(アプレットではありません)。

アイデアは?

役に立ちましたか?

解決

これは、MACアドレスを使用するのが一般的であるネットワークカードに関連付けられています。

アドレスは、次のAPIを介してJava 6の中で提供されています:

Java 6のドキュメントについてハードウェアアドレス

私はJavaでそれを使用していないが、他のネットワーク識別アプリケーションのために、それが参考にされています。

他のヒント

MAC アドレスの問題は、コンピュータに多数のネットワーク アダプタが接続される可能性があることです。最新のもののほとんどには、デフォルトで 2 つあります (Wi-Fi + ケーブル)。このような状況では、どのアダプタの MAC アドレスを使用する必要があるかを知る必要があります。私のシステムで MAC ソリューションをテストしましたが、4 つのアダプター (ケーブル、WiFi、Virtual Box 用の TAP アダプターと Bluetooth 用の 1 つ) があり、どの MAC を使用するべきかを決定できませんでした...現在使用中の (アドレスが割り当てられている) アダプターを使用することにした場合、誰かが自分のラップトップを持ち出してケーブル アダプターから Wi-Fi に切り替える可能性があるため、新たな問題が発生します。このような状態では、ラップトップをケーブルで接続したときに保存された MAC が無効になります。

たとえば、これらは私のシステムで見つかったアダプターです。

lo MS TCP Loopback interface
eth0 Intel(R) Centrino(R) Advanced-N 6205
eth1 Intel(R) 82579LM Gigabit Network Connection
eth2 VirtualBox Host-Only Ethernet Adapter
eth3 Sterownik serwera dostepu do sieci LAN Bluetooth

それらをリストするために使用したコード:

Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
    NetworkInterface ni = nis.nextElement();
    System.out.println(ni.getName() + " " + ni.getDisplayName());
}

このページで聞くオプションのうち、私にとって最も受け入れられるもので、私のソリューションで使用したものは@Ozhan Duzによるもので、もう1つはJACOBを使用した@finnwの回答に似ており、言及する価値があるのは com4j - WMIを利用したサンプルを公開しています ここ:

ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
ISWbemServices wbemServices = wbemLocator.connectServer("localhost","Root\\CIMv2","","","","",0,null);
ISWbemObjectSet result = wbemServices.execQuery("Select * from Win32_SystemEnclosure","WQL",16,null);
for(Com4jObject obj : result) {
    ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
    System.out.println(wo.getObjectText_(0));
}

これにより、コンピュータのシリアル番号とともにいくつかのコンピュータ情報が出力されます。この例で必要なすべてのクラスは、maven-com4j-plugin によって生成される必要があることに注意してください。maven-com4j-plugin の設定例:

<plugin>
    <groupId>org.jvnet.com4j</groupId>
    <artifactId>maven-com4j-plugin</artifactId>
    <version>1.0</version>
    <configuration>
        <libId>565783C6-CB41-11D1-8B02-00600806D9B6</libId>
        <package>win.wmi</package>
        <outputDirectory>${project.build.directory}/generated-sources/com4j</outputDirectory>
    </configuration>
    <executions>
        <execution>
            <id>generate-wmi-bridge</id>
            <goals>
                <goal>gen</goal>
            </goals>
        </execution>
    </executions>
</plugin>

上記の設定は、プロジェクト フォルダーの target/generated-sources/com4j ディレクトリにクラスを生成するようにプラグインに指示します。

見たい方へ 使用する準備ができて 解決策として、Windows、Linux、および Mac OS でマシン SN を取得するために作成した 3 つのクラスへのリンクを含めます。

OSHI のプロジェクトは、をプラットフォームに依存しないのハードウェアユーティリティを提供します。

Mavenの依存ます:

<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>LATEST</version>
</dependency>

たとえば、あなたが独自にマシンを識別するために、次のコードのようなものを使用することができます:

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

class ComputerIdentifier
{
    static String generateLicenseKey()
    {
        SystemInfo systemInfo = new SystemInfo();
        OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
        HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
        CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();
        ComputerSystem computerSystem = hardwareAbstractionLayer.getComputerSystem();

        String vendor = operatingSystem.getManufacturer();
        String processorSerialNumber = computerSystem.getSerialNumber();
        String processorIdentifier = centralProcessor.getIdentifier();
        int processors = centralProcessor.getLogicalProcessorCount();

        String delimiter = "#";

        return vendor +
                delimiter +
                processorSerialNumber +
                delimiter +
                processorIdentifier +
                delimiter +
                processors;
    }

    public static void main(String[] arguments)
    {
        String identifier = generateLicenseKey();
        System.out.println(identifier);
    }
}

私のマシン用の出力:

Microsoft#57YRD12#Intel64 Family 6 Model 60 Stepping 3#8

少なくともプロセッサのシリアル番号が異なりますので、お出力は異なります。

あなたはこのユニークなIDとはどのように過ごしたいですか?たぶん、あなたはこのIDなしであなたがやりたいことができます。

MACアドレスは多分1つのオプションがあるが、これは、ユーザーがコンピュータのMACアドレスを変更することができますので、一意のIDを信頼されていません。

このリンクの上のマザーボードまたはプロセッサIDチェックを取得します。

Windows の場合のみ、次を使用してマザーボード ID を取得できます。 WMI, 、次のようなCOMブリッジ経由 ジェイコブ.

例:

import java.util.Enumeration;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

public class Test {
    public static void main(String[] args) {
        ComThread.InitMTA();
        try {
            ActiveXComponent wmi = new ActiveXComponent("winmgmts:\\\\.");
            Variant instances = wmi.invoke("InstancesOf", "Win32_BaseBoard");
            Enumeration<Variant> en = new EnumVariant(instances.getDispatch());
            while (en.hasMoreElements())
            {
                ActiveXComponent bb = new ActiveXComponent(en.nextElement().getDispatch());
                System.out.println(bb.getPropertyAsString("SerialNumber"));
                break;
            }
        } finally {
            ComThread.Release();
        }
    }
}

また、MAC アドレスを使用してマシンを識別することを選択した場合は、WMI を使用して、インターフェイスが USB 経由で接続されているかどうかを判断できます (USB アダプタを除外する場合)。

WMI 経由でハード ドライブ ID を取得することもできますが、これは信頼できません。

MAC アドレスを識別子として使用する場合は注意してください。私はいくつかの落とし穴を経験しました。

  1. OS X では、アクティブ/アップしていないイーサネット ポートは、 NetworkInterface.getNetworkInterfaces() 列挙。
  2. 適切な OS 権限があれば、カードの MAC アドレスを変更するのは非常に簡単です。
  3. Java には、「仮想」インターフェイスを正しく識別しない癖があります。を使用しても、 NetworkInterface.isVirtual() いつも真実を教えてくれるわけではありません。

上記の問題はあっても、ライセンスをハードウェアでロックするための純粋な Java のアプローチとしては、これが最善であると私は考えています。

あなたの要件のすべてを知っているわけではありません。たとえば、あなたが独自に世界のすべてのコンピュータからコンピュータを識別しようとしている、またはあなただけのユニークなアプリケーションのユーザーのセットからコンピュータを識別しようとしているです。また、あなたは、システム上のファイルを作成することができますか?

あなたがファイルを作成することができるならば。あなたは、ファイルを作成し、一意のIDとして、ファイルの作成時刻を使用することができます。あなたがユーザ空間でそれを作成した場合、それは一意に特定のマシン上のアプリケーションのユーザーを識別します。あなたがどこかに地球を作成した場合、それは一意にマシンを識別することができます。

ここでも、ほとんどのものとして、どのように速く十分に速く..ですか、この場合には、ユニーク十分かユニークである。

これを見たほうがいいと思います リンク ...Mac+OS+HostName+などのいくつかの識別子を使用して、混合キーを作成できますCPUID+マザーボードのシリアル番号.

の使用法 マック タスクが一意の ID をシステムに記録することに関するものである場合、id が最も簡単な方法です。

mac ID の変更は可能ですが、それぞれのデバイスを交換すれば、システムの他の ID の変更も可能です。

したがって、一意の ID に何が必要なのかが不明でない限り、適切な解決策を見つけることができない可能性があります。

ただし、以下のリンクは MAC アドレスを抽出するのに役立ちます。http://www.stratos.me/2008/07/find-mac-address-using-java/

一意のWindowsマシンを識別するための

。 あなたが代替方法の戦略を持っているためにWMICを使用するときに確認してください。すべてのマシン上の「WMIC BIOS GETのserialNumber」になることがありません仕事以来、あなたは追加のメソッドを持っている必要があります。

# Get serial number from bios
wmic bios get serialnumber
# If previous fails, get UUID
wmic csproduct get UUID
# If previous fails, get diskdrive serialnumber
wmic DISKDRIVE get SerialNumber

リソース: ベストウェイには、ユニークなAのWindowsマシンを識別します http://www.nextofwindows.com/最高ウェイ・ツー・一意に識別--窓マシン/

私は(私は、Windowsが使用信じものです)マザーボードのシリアル番号を使用リリースのために書かれているJavaプログラムで

;私の関数が値を取得するために、WMIを使用して、一時的なVBスクリプトを作成するようしかし、これはWindowsでのみ動作します。

public static String getMotherboardSerial() {
      String result = "";
        try {
          File file = File.createTempFile("GetMBSerial",".vbs");
          file.deleteOnExit();
          FileWriter fw = new FileWriter(file);

          String vbs =
             "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
            + "Set colItems = objWMIService.ExecQuery _ \n"
            + "   (\"Select * from Win32_ComputerSystemProduct\") \n"
            + "For Each objItem in colItems \n"
            + "    Wscript.Echo objItem.IdentifyingNumber \n"
            + "Next \n";

          fw.write(vbs);
          fw.close();
          Process gWMI = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
          BufferedReader input = new BufferedReader(new InputStreamReader(gWMI.getInputStream()));
          String line;
          while ((line = input.readLine()) != null) {
             result += line;
             System.out.println(line);
          }
          input.close();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        result = result.trim();
        return result;
      }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top