Java、Windows、MacOS、および可能であれば Linux を搭載したコンピューターに固有の ID を取得したいと考えています。ディスクの UUID、マザーボードの S/N などの可能性があります。
Runtime.getRuntime().exec
使用できます (アプレットではありません)。
アイデア?
Java、Windows、MacOS、および可能であれば Linux を搭載したコンピューターに固有の ID を取得したいと考えています。ディスクの UUID、マザーボードの S/N などの可能性があります。
Runtime.getRuntime().exec
使用できます (アプレットではありません)。
アイデア?
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つは@finnwの回答に似ており、彼がJACOBを使用した場所であり、言及する価値があります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 つのクラスへのリンクを含めます。
ネットワーク カードに関連付けられている MAC アドレスを使用するのが一般的です。
このアドレスは、次の API を介して Java 6 で使用できます。
Java で使用したことはありませんが、他のネットワーク識別アプリケーションでは役に立ちました。
この一意の ID で何をしたいですか? この ID がなくてもやりたいことができるかもしれません。
MAC アドレスはオプションの 1 つかもしれませんが、ユーザーはコンピューターの MAC アドレスを変更できるため、これは信頼できる一意の ID ではありません。
マザーボードまたはプロセッサ ID を取得するには、このリンクで確認してください。
Windows の場合のみ、JACOBなどの COM ブリッジ経由でWMIを使用してマザーボード ID を取得できます。
例:
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 を取得することもできますが、これは信頼できません。
あなたのすべての要件を知っているわけではありません。たとえば、世界中のすべてのコンピューターから 1 つのコンピューターを一意に識別しようとしているのですか、それともアプリケーションの一連のユーザーから 1 つのコンピューターを一意に識別しようとしているだけですか。また、システム上にファイルを作成できますか?
ファイルを作成できる場合。ファイルを作成し、ファイルの作成時間を一意の ID として使用できます。ユーザー空間で作成すると、特定のマシンでアプリケーションのユーザーを一意に識別します。グローバルな場所に作成した場合、マシンを一意に識別することができます。
繰り返しますが、ほとんどのものと同様に、どれだけ速いかで十分です..またはこの場合、どれだけユニークかで十分です。
MAC アドレスを識別子として使用する場合は注意してください。私はいくつかの落とし穴を経験しました:
上記の問題があっても、ライセンスをハードウェアでロックするには、これが純粋な Java の最善のアプローチだと思います。
私はあなたがこのリンクを見るべきだと思います...あなたはmac+os + hostname + cpuid +マザーボードのシリアル番号のようないくつかの識別子を使って混合キーを作ることができます。
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/
タスクが一意の ID をシステムに記録することに関するものである場合、 MAC IDの使用は最も簡単な方法です。
mac id の変更は可能ですが、システムの他の id の変更も可能であり、それぞれのデバイスが交換されます。
そのため、一意の ID に何が必要かがわからない場合を除き、適切な解決策を見つけることができない場合があります。
ただし、以下のリンクは、MAC アドレスの抽出に役立ちます。 http://www.stratos.me/2008/07/find-mac-address-using-java/
私がリリース用に書いた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;
}