什么是好的唯一 PC 标识符?

发布于 2024-09-13 18:08:20 字数 374 浏览 6 评论 0原文

我一直在查看本教程中的代码,我发现它使用 My.Computer.Name 保存不应在计算机之间漫游的设置。然而,用户完全有可能拥有两台同名的电脑。例如,如果他们想在每台 PC 上使用相同的用户名,那么他们很可能最终会拥有两台名为 Username-PC 的 PC。

识别不同电脑的好方法有哪些? PC 是否有与其关联的 GUID,或者我应该考虑从某些硬件中提取序列号?我不在乎重新安装 Windows 后标识是否仍然存在。

(我链接的教程是在 VB.Net 中,但我是在 C# 中实现的)

I've been looking at the code in this tutorial, and I found that it uses My.Computer.Name to save settings that shouldn't roam between computers. It's entirely possible, however, for a user to have two identically named PCs. If they wanted to have the same username on each PC, for example, they may very well end up with two PCs named Username-PC.

What are some good methods of identifying different PCs? Do PCs have GUIDs associated with them, or should I look into pulling the serial number off of some hardware? I don't care if the identification persists through reinstallation of Windows.

(The tutorial I linked is in VB.Net, but I'm implementing it in C#)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

当梦初醒 2024-09-20 18:08:20

一些好的标识符:

  • MAC 地址:很容易获得,而且通常是唯一的。然而,它可以很容易地被欺骗/改变,所以这取决于它需要有多独特。
  • CPU 序列号:它在许多旧系统上不可用,但它是存在的。请查看此 MSDN 页面。它不会改变,但它与计算机绑定。
  • HDD 序列号:它可能不会改变,但如果 HD 出现故障,可能会很麻烦。请查看此 MSDN 页面

Some good identifiers:

  • MAC Address: It's fairly easy to get at, and it's usually unique. However, it can be spoofed/changed rather easily, so it depends on how unique it needs to be.
  • CPU Serial Number: It's not available on lots of older systems, but it's there. Check out this MSDN page. It won't change, but it's bound to a computer.
  • HDD Serial Number: It's likely to not change, but can be a nuisance if the HD fails. Check out this MSDN page.
遗失的美好 2024-09-20 18:08:20

如果您使用的是 Windows,则 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProductId 对于每台计算机/每个 Windows 安装都是唯一的。正如其他一些答案一样,MAC 地址、Proc SN 和 HD SN 在 Windows 重新安装/双启动情况下将保持不变。

If you are on windows HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProductId is unique per machine/per windows install. where as in some of the other answers like the MAC address, Proc SN, and HD SN will stay the same between windows reinstalls/dual boot situations.

虫児飞 2024-09-20 18:08:20

这个问题的真正答案是:不存在这样的事情。

有几种“足够接近”的解决方案,但每一种都有其自身的局限性。

所有硬件 ID - 硬件更改。而且,在许多情况下,您可以更改这些标识符(例如,MAC 欺骗)。

正如我已经评论过的,SID 也不是那么好,因为如果计算机是从映像安装的,SID 不会改变。 SID 是由 Windows 安装生成的,如果未安装 Windows,而是从映像复制的,SID 不会更改(尽管由于 关于“安全风险”的神话 - 你不能指望这一点)。

计算机名称 - 嗯,正如前面提到的,它们应该是唯一的,但并没有以任何方式强制执行。

您可以实现的另一个解决方案是生成您自己的唯一标识符并将其存储在本地(假设您可以这样做)。同样,如果您的计算机是使用您的应用程序进行映像的,则此解决方案将不起作用。

最适合您的解决方案实际上取决于您想要实现的目标。
我在一个相当大的网络中遇到了同样的问题,就我而言,最好的解决方案是计算机的名称。
如果您绝对确定您的进程不会被成像,我将使用 Guid 生成一个唯一标识符,因为它可能是最安全的。

The real answer to that question: There is no such thing.

There are several "close enough" solutions, but each one of those has it's own limitation.

All the hardware IDs - Hardware changes. And, in many cases you can change those identifiers (For example, MAC spoofing).

The SID, as I've already commented, Is not that good as well, because the SID won't change if the computer was installed from an image. The SID is generated by windows installation, if windows wasn't installed, but copied from an image, the SID won't change (although it is common to regenerate it because of a myth about "security risk" - you can't count on that).

Computer name - Well, as mentioned, They suppose to be unique, but it's not enforced in any way.

Another solution you can implement is to generate you own unique identifier and store it locally (assuming you can do such thing). Again, this solution won't work if your computer was imaged with your application.

The best solution for you really depends on what you are trying to accomplish.
I had the same problem with a quite large network, and the best solution in my case was the computer's name.
If you are absolutely sure that your process won't be imaged, I would generate a unique identifier using Guid because it will probably be the safest.

甜扑 2024-09-20 18:08:20

这是唯一标识一台计算机的方法。
使用 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
并获取每个物理驱动器的“序列号”。在这种情况下,

    foreach (ManagementObject item in searcher.Get())

应该找到多个项目

Here is a way to uniquely identify a computer.
Using System.Management to get Win32_BIOS, you can get unique values from your machine's BIOS.

See: Win32_BIOS class, 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();
}

With similar logic, you can also step through "Win32_DiskDrive";
http://msdn.microsoft.com/en-us/library/aa394132.aspx;
and get "SerialNumber" for each physical drive. In this case, the

    foreach (ManagementObject item in searcher.Get())

should find multiple items

胡大本事 2024-09-20 18:08:20

采用三个半唯一且半恒定的标识符。使用三分之二足以进行肯定识别的规则。更新偶尔出错的三分之一的注册数据。

Take three identifiers that are semi-unique and semi-constant. Use the rule that 2 out of 3 is sufficient for a positive identification. Update the registered data for the 1 out of 3 that is occasionally wrong.

画离情绘悲伤 2024-09-20 18:08:20

使用网卡的 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;
}

Use the network card's MAC address. It's supposed to be unique. It can be changed, though. It depends on how malicious you expect your users to be and how critical your application is.

Some sample code to do it:

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;
}
何处潇湘 2024-09-20 18:08:20

您可以使用的一件事是任何网络接口的 MAC。您还可以结合多个信息源。像 HDD 序列号、mac、处理器类型一样,从中计算哈希值。

One thing you can use is the MAC of any Network interface. You can also combine several sources of information. Like HDD Serial number, mac, processor type to calculate a hash from it.

一影成城 2024-09-20 18:08:20

我们使用 Win32_processor 中的 ProcessorIDWin32_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”),但后来我们发现主板的序列号可以不填,也可以统一填写:

  • OEM 填写
  • 默认字符串

因此,这种情况值得考虑。

另请记住,ProcessorID 编号在不同计算机上可能相同。

We use a combination of the ProcessorID from Win32_processor and the UUID from 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 = 
quot;{processorId}{systemId}";

Previously, we used a combination: processor ID ("Select ProcessorID From Win32_processor") and the motherboard serial number ("SELECT SerialNumber FROM Win32_BaseBoard"), but then we found out that the serial number of the motherboard may not be filled in, or it may be filled in with uniform values:

  • To be filled by O.E.M.
  • None
  • Default string

Therefore, it is worth considering this situation.

Also keep in mind that the ProcessorID number may be the same on different computers.

伴我老 2024-09-20 18:08:20

我认为同一域中不可能有两台具有相同名称的 PC。您是否尝试过捕获域名?

I don't think it's possible to have two PC's with the same name on the same domain. Have you tried capturing the domain name?

‘画卷フ 2024-09-20 18:08:20

请查看此处:使用 .net 从戴尔计算机获取服务标签?< /a>

您可以从注册表中获取一些独特的数据。

Take a look here: Getting Service Tag from Dell Machine using .net?

You could snatch some unique data from the registry.

つ低調成傷 2024-09-20 18:08:20

每台计算机都有一个在正常情况下唯一的 SID。

Each computer has a SID that's unique under normal circumstances.

∝单色的世界 2024-09-20 18:08:20

在托管网络环境中,最好、最可靠的标识符可能是您创建的标识符,但也有一些缺点。

一些(很多?)制造商提供了一个实用程序,允许您设置存储在固件中的资产标签。这可能是一个可启动实用程序,也可能在 Windows 中运行,甚至可能内置于固件设置中。这个“标签”是一个任意文本字符串,您可以将其设置为您想要的任何内容,然后使用 WMIWin32_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");
    }
}

优点:

  • 您可以使用任何您想要的方案(例如合并日期、部门、递增整数、GUID 等)。
  • 您可以对所有机器使用一种方案,无论其制造商如何,而不必处理制造商特定的方案。
  • 通过自己分配和跟踪标识符,您可以保证它们是唯一的。不依赖制造商设置的标识符意味着制造商内部或制造商之间不存在重复的风险。
  • 该标识符存储在固件中(而不是硬盘驱动器上),因此它可以在重新格式化、升级等后继续存在,但也不会通过备份/映像/克隆进行复制。

缺点:

  • 您需要实际设置资产标签;在您这样做之前,它们都是空白的。
  • 设置机器的资产标签可能需要物理访问和重新启动。
  • 资产标签不是一次性写入的,因此可以更改或删除。
    • 受密码保护的固件应该在更改标签之前需要该密码,但这并不能保证。
  • 通过自己分配和跟踪标识符,不仅会产生分配和跟踪标识符的开销,而且如果不小心的话,还有可能引入重复项。
  • 为此目的使用资产标签要求所有计算机都支持设置资产标签并正确地将其报告给 WMI。

In a managed network environment, the best, most reliable identifier might be the one you create, but there are some downsides.

Some (many?) manufacturers provide a utility that allows you to set an asset tag that is stored in the firmware. This might be a bootable utility, or it might run within Windows, or it might even be built into the firmware setup. This "tag" is an arbitrary text string that you can set to whatever you want, and then read it back using WMI and the 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");
    }
}

Pros:

  • You can use whatever scheme you want (e.g. incorporating date, department, incrementing integers, GUIDs, etc.).
  • You can use one scheme for all machines regardless of their manufacturer, instead of having to handle manufacturer-specific schemes.
  • By allocating and tracking the identifiers yourself, you can guarantee that they are unique. Not relying on an identifier set by the manufacturer means there is no risk of duplicates within a manufacturer or between manufacturers.
  • The identifier is stored in the firmware — not on the hard drive — so it will survive reformatting, upgrades, etc. but also not be duplicated by backups/imaging/cloning.

Cons:

  • You need to actually set the asset tag; they'll all be blank until you do so.
  • Setting a machine's asset tag may require physical access and a reboot.
  • Asset tags are not write-once and could, therefore, be changed or erased.
    • Password-protected firmware should require that password before changing the tag, but that's not guaranteed.
  • By allocating and tracking the identifiers yourself, there's not only the overhead of...allocating and tracking the identifiers, but also the possibility that you'll introduce duplicates if you're not careful.
  • Using asset tags for this purpose requires that all machines support setting an asset tag and properly report it to WMI.
半窗疏影 2024-09-20 18:08:20

此链接中有一个带有完整说明的示例代码,用于获取 CPU 和 HD 驱动器 ID:http://www .vcskicks.com/hardware_id.php

将此 dll 添加到

 System.Management.dll

CPU ID

string cpuInfo = string.Empty;
ManagementClass mc = new ManagementClass("win32_processor");
ManagementObjectCollection moc = mc.GetInstances();

foreach (ManagementObject mo in moc)
{
     if (cpuInfo == "")
     {
          //Get only the first CPU's ID
          cpuInfo = mo.Properties["processorID"].Value.ToString();
          break;
     }
}
return cpuInfo;

和硬盘 ID(卷串行)的引用中:

ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""" + drive + @":""");
dsk.Get();
string volumeSerial = dsk["VolumeSerialNumber"].ToString();

There is a sample code with complete notes in this link for getting CPU and HD Drive ID: http://www.vcskicks.com/hardware_id.php

add this dll to refrences

 System.Management.dll

for CPU ID:

string cpuInfo = string.Empty;
ManagementClass mc = new ManagementClass("win32_processor");
ManagementObjectCollection moc = mc.GetInstances();

foreach (ManagementObject mo in moc)
{
     if (cpuInfo == "")
     {
          //Get only the first CPU's ID
          cpuInfo = mo.Properties["processorID"].Value.ToString();
          break;
     }
}
return cpuInfo;

and for Hard Drive ID (Volume Serial):

ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""" + drive + @":""");
dsk.Get();
string volumeSerial = dsk["VolumeSerialNumber"].ToString();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文