Java、Windows、MacOS、可能であればLinuxを搭載したコンピューターに固有のIDを取得したいと思います。ディスクUUID、マザーボードS/N ...
Runtime.getRuntime().exec
を使用できます(アプレットではありません)。
アイデア?
ネットワークカードに関連付けられているMACアドレスを使用するのが一般的です。
アドレスは、次のAPIを介してJava 6で利用可能です。
Javaでは使用していませんが、他のネットワーク識別アプリケーションには役立ちました。
MACアドレスの問題は、コンピューターに多数のネットワークアダプターが接続されている可能性があることです。最新のもののほとんどは、デフォルトで2つあります(wi-fi +ケーブル)。このような状況では、どのアダプターのMACアドレスを使用する必要があるかを知る必要があります。システムでMACソリューションをテストしましたが、4つのアダプター(ケーブル、WiFi、Virtual Box用のTAPアダプターとBluetooth用のアダプター)があり、どの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を利用するサンプルが利用可能です here :
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ディレクトリーにクラスを生成するようプラグインに指示します。
ready-to-useソリューションを見たい人のために、WindowsでマシンSNを取得するために書いた3つのクラスへのリンクを含めます。 LinuxおよびMac OS:
OSHI
プロジェクトは、platform-independentハードウェアユーティリティを提供します。
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を取得するには、この link を確認してください。
Windowsでのみ、 [〜#〜] wmi [〜#〜] を使用してマザーボードIDを取得できます。COMブリッジでは [〜#〜] jacob [〜#〜 ] 。
例:
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アドレスを識別子として使用する場合は注意してください。私はいくつかの落とし穴を経験しました:
上記の問題があったとしても、ライセンスをロックするハードウェアに対する最善の純粋なJavaアプローチです。
すべての要件を知らない。たとえば、世界のすべてのコンピューターからコンピューターを一意に識別しようとしているのですか、それともアプリケーションの一連のユーザーからコンピューターを一意に識別しようとしているのですか。また、システム上にファイルを作成できますか?
ファイルを作成できる場合。ファイルを作成し、ファイルの作成時間を一意のIDとして使用できます。ユーザー空間で作成すると、特定のマシン上のアプリケーションのユーザーを一意に識別します。グローバルな場所に作成した場合、マシンを一意に識別できます。
繰り返しになりますが、ほとんどの場合と同様に、どのくらいの速さで十分に高速です。
これを見る必要があると思います link ... mac + os + hostname + cpu id + motherboard serial番号 。
[〜#〜] mac [〜#〜]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
リソース:Windowsマシンを一意に識別する最良の方法 http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine/
リリース用に作成したJavaプログラムでは、マザーボードのシリアル番号を使用しました(これはWindowsが使用しているものです)。ただし、これは、私の関数が値を取得するために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;
}