我一直在查看this tutorial中的代码,我发现它使用My.Computer.Name
来保存不应在计算机之间漫游的设置。但是,完全有可能用户拥有两台名称相同的PC。例如,如果他们想在每台PC上使用相同的用户名,他们最终可能会得到两台名为Username-PC的PC。
识别不同PC有哪些好方法? PC是否有与之关联的GUID,或者我应该考虑从某些硬件中提取序列号?我不关心通过重新安装Windows是否仍然存在识别。
(我链接的教程是在VB.Net中,但我在C#中实现它)
答案 0 :(得分:43)
一些好的标识符:
答案 1 :(得分:18)
如果你在Windows上HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProductId
每台机器/每个Windows安装都是唯一的。在某些其他答案中,如MAC地址,Proc SN和HD SN将在Windows重新安装/双启动情况之间保持不变。
答案 2 :(得分:11)
这个问题的真正答案:没有这样的事情。
有几个“足够接近”的解决方案,但每个解决方案都有自己的限制。
所有硬件ID - 硬件更改。并且,在许多情况下,您可以更改这些标识符(例如,MAC欺骗)。
正如我已经评论的那样,SID也不是那么好,因为如果从图像安装计算机,SID不会改变。 SID是由Windows安装生成的,如果未安装Windows,但是从图像复制,则SID不会更改(尽管由于myth about "security risk"而重新生成它 - 您不能指望这一点)。
计算机名称 - 嗯,如上所述,他们认为它是独一无二的,但它没有以任何方式强制执行。
您可以实现的另一个解决方案是生成您自己的唯一标识符并将其存储在本地(假设您可以执行此类操作)。同样,如果您的计算机是使用您的应用程序成像的,那么此解决方案将无效。
最适合您的解决方案取决于您要完成的任务。 我有一个相当大的网络问题,在我的情况下,最好的解决方案是计算机的名称。 如果您完全确定您的进程不会被成像,我会使用Guid生成一个唯一的标识符,因为它可能是最安全的。
答案 3 :(得分:9)
这是一种唯一识别计算机的方法。 使用System.Management获取Win32_BIOS,您可以从计算机的BIOS中获取唯一值。
请参阅:Win32_BIOS类,http://msdn.microsoft.com/en-us/library/aa394077.aspx
using System.Management;
string UniqueMachineId()
{
StringBuilder builder = new StringBuilder();
String query = "SELECT * FROM Win32_BIOS";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
// This should only find one
foreach (ManagementObject item in searcher.Get())
{
Object obj = item["Manufacturer"];
builder.Append(Convert.ToString(obj));
builder.Append(':');
obj = item["SerialNumber"];
builder.Append(Convert.ToString(obj));
}
return builder.ToString();
}
使用类似的逻辑,您也可以单步执行“Win32_DiskDrive”; http://msdn.microsoft.com/en-us/library/aa394132.aspx; 并为每个物理驱动器获取“SerialNumber”。在这种情况下,
foreach (ManagementObject item in searcher.Get())
应该找到多个项目
答案 4 :(得分:3)
取三个半独特和半常数的标识符。使用3个中的2个足以进行肯定识别的规则。更新偶尔出错的3个中的1个的注册数据。
答案 5 :(得分:2)
使用网卡的MAC地址。它应该是独一无二的。但它可以改变。这取决于您对用户的期望程度以及您的应用程序的重要程度。
一些示例代码:
public string GetMACAddress() {
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
string MACAddress = String.Empty;
foreach (ManagementObject mo in moc) {
if (MACAddress == String.Empty) { // only return MAC Address from first card
if ((bool)mo["IPEnabled"] == true) MACAddress = mo["MacAddress"].ToString();
}
mo.Dispose();
}
return MACAddress;
}
答案 6 :(得分:1)
您可以使用的一件事是任何网络接口的MAC。您还可以组合多种信息来源。像HDD序列号,mac,处理器类型一样从中计算哈希值。
答案 7 :(得分:0)
我认为在同一个域中有两个同名的PC是不可能的。您是否尝试过捕获域名?
答案 8 :(得分:0)
看看这里:Getting Service Tag from Dell Machine using .net?
您可以从注册表中抓取一些独特的数据。
答案 9 :(得分:0)
每台计算机都有一个在正常情况下唯一的SID。
答案 10 :(得分:0)
在受管网络环境中,最好,最可靠的标识符可能是您创建的 标识符,但是存在一些缺点。
一些(许多?)制造商提供了一个实用程序,可让您设置存储在固件中的资产标签。这可能是可引导的实用程序,或者可能在Windows中运行,甚至可能内置在固件设置中。此“标签”是一个任意文本字符串,您可以将其设置为任意文本,然后使用WMI和Win32_SystemEnclosure
class ...
string[] selectedProperties = new string[] { "SMBIOSAssetTag" };
ObjectQuery enclosureQuery = new SelectQuery("Win32_SystemEnclosure", null, selectedProperties);
using (ManagementObjectSearcher enclosureSearcher = new ManagementObjectSearcher(enclosureQuery))
using (ManagementObjectCollection enclosureCollection = enclosureSearcher.Get())
{
foreach (ManagementObject enclosure in enclosureCollection)
{
string assetTag = (string) enclosure.GetPropertyValue("SMBIOSAssetTag");
}
}
优点:
缺点:
答案 11 :(得分:0)
我们结合使用了ProcessorID
中的Win32_processor
和UUID
中的Win32_ComputerSystemProduct
:
ManagementObjectCollection mbsList = null;
ManagementObjectSearcher mos = new ManagementObjectSearcher("Select ProcessorID From Win32_processor");
mbsList = mos.Get();
string processorId = string.Empty;
foreach (ManagementBaseObject mo in mbsList)
{
processorId = mo["ProcessorID"] as string;
}
mos = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct");
mbsList = mos.Get();
string systemId = string.Empty;
foreach (ManagementBaseObject mo in mbsList)
{
systemId = mo["UUID"] as string;
}
var compIdStr = $"{processorId}{systemId}";
以前,我们使用了以下组合:处理器ID("Select ProcessorID From Win32_processor"
)和主板序列号("SELECT SerialNumber FROM Win32_BaseBoard"
),但随后发现主板序列号可能没有填写,或者可以用统一的值填充
因此,值得考虑这种情况。
还请记住,ProcessorID
号在不同的计算机上可能是相同的。
答案 12 :(得分:-1)
有一个带有完整注释here
的示例代码