My.Computer.Name
保存不应该在计算机之间漫游的设置。然而,用户很可能会有两台同名的PC。例如,如果他们想在每台PC上使用相同的用户名,他们很可能最终会得到两台名为“用户名-PC”的PC。有什么好的方法来识别不同的PC吗?PC是否与GUID相关联,或者我应该尝试从某些硬件上获取序列号?我不在乎标识是否会持续到重新安装Windows。
(我链接的教程是VB.Net的,但我正在用C#实现它)
My.Computer.Name
保存不应该在计算机之间漫游的设置。然而,用户很可能会有两台同名的PC。例如,如果他们想在每台PC上使用相同的用户名,他们很可能最终会得到两台名为“用户名-PC”的PC。SerialNumber
属性获取 CPU 序列号。在 MSDN 链接中查找并使用 Ctrl+F 搜索 "SerialNumber",阅读该属性所适用的操作系统的最后一个注释。 - qJakeHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProductId
是每台机器/每个Windows安装的唯一标识,而其他答案中的MAC地址、处理器SN和硬盘SN则在Windows重装或双启动情况下保持不变。HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProductId
和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid
中的ID之间有什么区别? - Skipper回答这个问题的真实答案是:没有这样的东西。
有几个“接近”的解决方案,但每一个都有自己的限制。
所有硬件ID - 硬件会更改。而且,在许多情况下,您可以更改这些标识符(例如,MAC欺骗)。
正如我已经评论过的那样,SID也不太好,因为如果从映像安装计算机,则SID不会更改。SID由Windows安装生成,如果未安装Windows,而是从映像中复制,则SID不会更改(尽管通常会重新生成它,因为关于“安全风险”的错误传言 - 你不能指望它)。
计算机名称 - 好吧,正如提到的那样,它们应该是唯一的,但没有以任何方式强制执行。
您可以实施的另一种解决方案是生成自己的唯一标识符并在本地存储它(假设您可以这样做)。再次强调,如果使用您的应用程序对计算机进行了成像,则此解决方案将无法工作。
对于您来说最好的解决方案实际上取决于您想要实现什么目标。我在一个相当大的网络中遇到了同样的问题,我的情况下最好的解决方案是使用计算机名称。如果您绝对确定您的进程不会被成像,我将使用Guid生成唯一标识符,因为它可能是最安全的。
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())
应该找到多个项目
使用三个半唯一且半恒定的标识符。根据规则,只需其中两个即可进行正确认证。更新偶尔错误的那个标识符中的注册数据。
使用网络卡的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;
}
你可以使用任何网络接口的MAC地址。你也可以结合多个信息源,如硬盘序列号、MAC地址、处理器类型来计算哈希值。
我们使用来自Win32_processor
的ProcessorID
和来自Win32_ComputerSystemProduct
的UUID
的组合:
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
编号在不同计算机上可能相同。
Win32_SystemEnclosure
类 读取它...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");
}
}
优点:
缺点:
我认为在同一域中不可能有两台计算机具有相同的名称。您尝试过捕获域名吗?