这可能就是为什么它不能在不同版本的 Windows 中可靠工作的原因
不,这不是原因。此问题是由您的 EXE 项目的平台目标选择引起的。项目 + 属性、构建选项卡、平台目标组合框。您将其设置为 x86 而不是 AnyCPU。在 VS2012 上,“首选 32 位”复选框很重要。此设置强制您的程序在 64 位版本的 Windows 上以 32 位模式运行。这有许多副作用,这里重要的是重定向对注册表项的访问。您的程序实际上正在读取 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\MachineGuid 的值。哪个不存在。
x86 选项是 VS2010 及更高版本的默认选项,之前 AnyCPU 是默认选项。Microsoft 更喜欢 x86,Visual Studio 更适合 32 位模式进程。特别是在调试时,VS 本身是一个 32 位进程,因此如果您的程序在 64 位模式下执行,则需要远程调试器。其中有一些限制,例如不支持混合模式调试。编辑 + 继续功能仅适用于 32 位代码。但是,如果您在 AnyCPU 上进行了设置,您的程序本身会“更好地”运行,包括不会被文件系统和 Windows 内置的注册表重定向 appcompat 功能所困扰。
如果您真的坚持使用 x86 模式,通常是因为您依赖于无法更新的 32 位本机代码,那么下一个解决方法是使用 .NET 4+ RegistryKey.OpenBaseKey() 方法。它允许您通过 RegistryView.Registry64,确保您将读取非重定向键。
当然,使用 WMI 是一种解决方法。请记住,当您使用 Win32_OperatingSystem.SerialNumber 时,您不会读取相同的信息。我不清楚不同机器上的密钥在多大程度上是可靠随机的,我们只是说这个值对于那些对为您的产品支付许可费不太感兴趣的用户来说是一个非常有吸引力的目标。
最后但并非最不重要的一点是,请考虑生成完全不依赖于 Windows 的您自己的唯一 ID 非常容易。具有相当大的优势,即当您的客户在他的机器上更新 Windows 时,您不会惹恼他。只需使用一次 Guid.NewGuid() 并将值存储在文件中。当驱动器出现故障时,这将丢失,但这通常也会导致您的产品失效。