Java で一意のコンピュータ識別子 (ディスク ID やマザーボード ID など) を取得するにはどうすればよいですか?
-
22-09-2019 - |
質問
Windows、MacOS、そして可能であれば Linux 上で Java を搭載したコンピュータに固有の ID を取得したいと考えています。それはディスク UUID、マザーボード S/N である可能性があります...
Runtime.getRuntime().exec
使用できます(アプレットではありません)。
アイデアは?
解決
これは、MACアドレスを使用するのが一般的であるネットワークカードに関連付けられています。
アドレスは、次のAPIを介して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 アドレスを識別子として使用する場合は注意してください。私はいくつかの落とし穴を経験しました。
- OS X では、アクティブ/アップしていないイーサネット ポートは、 NetworkInterface.getNetworkInterfaces() 列挙。
- 適切な OS 権限があれば、カードの MAC アドレスを変更するのは非常に簡単です。
- 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/
。 あなたが代替方法の戦略を持っているために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/最高ウェイ・ツー・一意に識別--窓マシン/ の
;私の関数が値を取得するために、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;
}