私は、次のようなスタックオーバーフローに多くの同様の質問があることを知っています:
...そしてさらに数十と私はそれらすべてを研究しました。
問題は、受け入れられた回答のいくつかが、完全に正しくない一意の識別子としてMACアドレスを示唆していることです。他のいくつかの回答は、より論理的に見えるさまざまなコンポーネントの組み合わせを使用することを提案しています。ただし、組み合わせを使用する場合は、どのコンポーネントが頻繁に変更される可能性が低いかを考慮する必要があります。数日前、CPUIDとMACの組み合わせを使用してWindows PCを一意に識別するソフトウェアライセンス問題のキージェネレーターを開発し、実際のテストまで、このアプローチで十分だと考えました。皮肉なことに、テストを行ったところ、3台のコンピューターがキージェネレーターで同じIDを返していることがわかりました。
それで、コンピュータを一意に識別する方法は本当にありますか?今のところ、WindowsPCで動作するようにキージェネレーターを作成する必要があります。私たちのシステムは.netで開発されているので、c#を使用する何らかの方法(可能であれば)は素晴らしいでしょう。
更新:
いくつかの混乱と明らかに誤った警報を作成して申し訳ありません。ハードウェア情報を取得する方法に誤りがあることがわかりました。私自身の混乱がなくなったので、主にこの質問を削除することを考えました。2つ以上のコンポーネントの組み合わせは、コンピューターを識別するのに十分であると信じています。しかし、同じことが将来他の人を傷つける可能性があるので、問題の原因を明らかにする必要があると思うので、それを維持することにしました。
これは私たちが行っていたことです(他のコードを除く):
getManagementInfo
関数を使用してMACとプロセッサIDを取得していました
_private String getManagementInfo(String StrKey_String, String strIndex)
{
String strHwInfo = null;
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + StrKey_String);
foreach (ManagementObject share in searcher.Get())
{
strHwInfo += share[strIndex];
}
}
catch (Exception ex)
{
// show some error message
}
return strHwInfo;
}
_
次に、必要に応じて、その関数を使用してMACアドレスを取得しました
_string strMAC = getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress");
_
そしてProcessorIDを取得します
_string strProcessorId = getManagementInfo("Win32_Processor", "ProcessorId");
_
この時点で、strMAC
には、複数のMACアドレスがある場合、複数のMACアドレスが含まれます。 1つだけを取るために、最初の17文字(12のMAC桁とその間の5つのコロン)を取りました。
_strMAC = strMAC.Length > 17 ? strMAC.Remove(17) : strMAC;
_
これが私たちが間違いを犯した場所です。 getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress")
は、実際に使用されていた追加のMACアドレスを多数返していたためです。たとえば、コマンドPrompt by getmac
コマンドでMACアドレスを検索すると、PCごとに1つまたは2つのMACアドレスが表示されました。これらはすべて異なっていました。しかし、getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress")
は4〜5個のMACアドレスを返し、そのうちのいくつかはすべてのコンピューターで同一でした。関数が返す最初のMACアドレスを他のものをチェックする代わりに取得したので、偶然にも同じMACアドレスがstrMAC
に取得されました。
Sowkot Osman による次のコードは、最初のアクティブ/有効なMACアドレスのみを返すことでトリックを実行します。
_private static string macId()
{
return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
}
private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
{
string result = "";
System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
if (mo[wmiMustBeTrue].ToString() == "True")
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
}
return result;
}
//Return a hardware identifier
private static string identifier(string wmiClass, string wmiProperty)
{
string result = "";
System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
return result;
}
_
しかし、私は同じプロセッサIDの問題については完全に正しかった。コマンドプロンプトに_wmic cpu get ProcessorId
_コマンドを入力すると、3つすべてが同じプロセッサIDを返しました。
ここで、プロセッサIDの代わりにマザーボードのシリアル番号を使用してMACアドレスと組み合わせることにしました。私たちの目的はこのように果たされると思います、そしてそれが場合によってはそうでないなら、私たちはそれらのいくつかの場合にそれを手放すべきです。
グローバルに一意のIDを取得する際の事実は、システム全体をセットアップしても変更されないIDはMACアドレスだけです。特定の製品のキーを生成する場合、それを行う最良の方法は、製品に一意のIDを割り当て、製品IDとMACアドレスを組み合わせることです。それが役に立てば幸い。
マザーボードのシリアル番号も追加するのはどうですか?例:
using System.management;
//Code for retrieving motherboard's serial number
ManagementObjectSearcher MOS = new ManagementObjectSearcher("Select * From Win32_BaseBoard");
foreach (ManagementObject getserial in MOS.Get())
{
textBox1.Text = getserial["SerialNumber"].ToString();
}
//Code for retrieving Processor's Identity
MOS = new ManagementObjectSearcher("Select * From Win32_processor");
foreach (ManagementObject getPID in MOS.Get())
{
textBox2.Text = getPID["ProcessorID"].ToString();
}
//Code for retrieving Network Adapter Configuration
MOS = new ManagementObjectSearcher("Select * From Win32_NetworkAdapterConfiguration");
foreach (ManagementObject mac in MOS.Get())
{
textBox3.Text = mac["MACAddress"].ToString();
}
上記のコメントに完全に同意します。
ソフトウェアライセンスについては、以下を使用できます。
コンピュータのMACアドレス(複数の場合はすべて取るNICカード)+ソフトウェア製品コード
有名な通信ベンダーのほとんどがこの手法を使用しています。
しかし、私は同じプロセッサIDの問題については完全に正しかった。コマンドプロンプトにwmiccpu get ProcessorIdコマンドを入力すると、3つすべてが同じプロセッサIDを返しました。
すべてのシステムが同じハイパーバイザー上で仮想マシンとして実行されている場合、プロセッサーIDは同じになります。
MACIDは問題ないようです。唯一のことは、MACが変更された場合に、ユーザーにアプリケーションをリセットするオプションを提供する必要があるということです。
カスタムキッチンがその方法のようです。
SMBIOS UUID(マザーボードシリアル)は堅牢ではありませんが、99%の場合は正常に機能します。ただし、一部のブランドでは、複数のコンピューターに同じUUIDを設定します(同じ生産バッチの場合もあります)。これを取得するには、ユーザーのWMIアクセスが必要です(管理者でない場合)。管理者の特権を要求する外部プロセスを開始することで、これを解決できます(codeproject.com/Articles/15848/WMI-Namespace-Securityを確認してください)。
Windowsの製品IDは良いかもしれませんが、状況によっては同じである可能性があると読みました( https://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine )同じ製品ID(プロダクトキーではない)が複数のコンピューターに存在する可能性があるかどうかを誰かが明確にできますか?
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuidは興味深いようです。これはWindowsのインストール時に生成され、変更された場合はWindowsを再アクティブ化する必要があります。
Macアドレスは興味深いものですが、最初のアドレスしか取得できないか、インターフェイスが無効になっている場合、または別のネットワークインターフェイスが追加されて最初に表示される場合などに一意のIDが変更されます。
ハードドライブのシリアル番号は素晴らしいですが、ゴーストをインストールすると、元のドライブのシリアル番号が上書きされる可能性があります...そしてHDシリアルは非常に簡単に変更できます。
最善の方法は、これらのマシンIDの組み合わせでIDを生成し、それらのIDを比較してマシンが同じかどうかを判断することです(つまり、少なくとも1つのMacアドレス+ SMBIOS UUIDまたは製品IDのいずれかが問題ない場合は、受け入れます)。