获取Windows序列号(原来是:从注册表中获取MachineGuid)
本文关键字:获取 注册表 MachineGuid Windows 序列号 原来 | 更新日期: 2023-09-27 17:51:02
我正试图从注册表中获取MachineGuid
,以便为我的许可证系统创建与操作系统的某种程度的绑定。从文档中我可以使用
string key = "HKEY_LOCAL_MACHINE''SOFTWARE''Microsoft''Cryptography";
string r = (string)Registry.GetValue(key, "MachineGuid", (object)"default");
得到它。此外,文档告诉我,当没有找到名称时,我得到"default"
,或者如果密钥不存在,我得到null
。如果我没有访问权限,我应该得到一个安全异常。
上面的代码给出了"default"
,这意味着没有找到名称。但是,如果我用RegEdit查看注册表,它就在那里。如何从没有管理员权限的应用程序中获取MachineGuid
值?
更新:当使用reg.exe
时,我没有问题获得值。
Update:我更新了标题,所以人们寻找一种独特的方式来确定Windows安装也到这里。
正如其他人已经指出的那样,您不应该直接从注册表中获得该值(这可能就是为什么它在不同版本的Windows中不可靠地工作)。
经过一番搜索,我找到了Win32_OperatingSystem
WMI课程。使用这个类,您可以实际获得Windows序列号。我花了一些时间来搜索和实验,但这是如何在c#中使用它。
确保你的项目中有System.Management.dll
引用:
using System.Management;
...
ManagementObject os = new ManagementObject("Win32_OperatingSystem=@");
string serial = (string)os["SerialNumber"];
使用[]
操作符,您可以获得类中的任何属性。
这可能就是为什么它不能在不同版本的Windows中可靠地工作
不,这不是原因。此问题是由EXE项目的平台目标选择引起的。项目+属性,构建选项卡,平台目标组合框。您将其设置为x86而不是AnyCPU。在VS2012上,"Prefer 32-bit"复选框很重要。此设置强制您的程序在64位版本的Windows上以32位模式运行。这有许多副作用,这里重要的是对注册表项的访问被重定向。你的程序实际上正在读取HKEY_LOCAL_MACHINE'SOFTWARE'Wow6432Node'Microsoft'Cryptography'MachineGuid的值。这是不存在的
x86选项是VS2010及更高版本的默认选项,之前AnyCPU是默认选项。微软更喜欢x86, Visual Studio更适合32位模式进程。特别是在调试时,VS本身是一个32位进程,因此如果您的程序以64位模式执行,则需要远程调试器。它有一些限制,比如不支持混合模式调试。编辑+继续功能只适用于32位代码。然而,如果你在AnyCPU上设置,你的程序本身就会"更好"地工作,包括不被Windows内置的文件系统和注册表重定向appcompat功能咬伤。
如果你真的被x86模式困住了,通常是因为你对32位本地代码有依赖而无法更新,那么下一个解决方法是使用。net 4+ RegistryKey.OpenBaseKey()方法。它允许你传递RegistryView。Registry64,确保您将读取非重定向键。
当然,使用WMI是一种变通方法。请记住,当您使用Win32_OperatingSystem.SerialNumber时,您是而不是读取相同的信息。我不太清楚这个密钥在不同机器上的可靠随机程度,我们只能说,对于那些对支付产品许可费也不太感兴趣的用户来说,这个值是一个非常有吸引力的目标。
最后但并非最不重要的是,一定要考虑到生成自己的唯一id非常容易,完全不依赖于Windows。有相当大的优势,你不会惹恼你的客户,当他在他的机器上更新Windows。只需使用一次Guid.NewGuid()并将值存储在文件中。当驱动器坏掉时,它会丢失,但这通常也会带走你的产品。
依我之见,没有一个答案能满足这个问题;非常直接地要求从注册表中读取MachineGuid的方法……所以我的回答是:你需要添加一个"microsoft . win32"的引用。这段代码是为了演示而编写的,应该相应地进行修改。
EDIT:有人错误地说x64代码是无用的。
在64位操作系统中,这是找到正确密钥的地方。
所以这个答案是唯一满足这个问题的答案。
private void buttonGetMachineGuid_Click(object sender, RoutedEventArgs e)
{
try
{
string x64Result = string.Empty;
string x86Result = string.Empty;
RegistryKey keyBaseX64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey keyBaseX86 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey keyX64 = keyBaseX64.OpenSubKey(@"SOFTWARE'Microsoft'Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
RegistryKey keyX86 = keyBaseX86.OpenSubKey(@"SOFTWARE'Microsoft'Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
object resultObjX64 = keyX64.GetValue("MachineGuid", (object)"default");
object resultObjX86 = keyX86.GetValue("MachineGuid", (object)"default");
keyX64.Close();
keyX86.Close();
keyBaseX64.Close();
keyBaseX86.Close();
keyX64.Dispose();
keyX86.Dispose();
keyBaseX64.Dispose();
keyBaseX86.Dispose();
keyX64 = null;
keyX86 = null;
keyBaseX64 = null;
keyBaseX86 = null;
if(resultObjX64 != null && resultObjX64.ToString() != "default")
{
MessageBox.Show(resultObjX64.ToString());
}
if(resultObjX86 != null && resultObjX86.ToString() != "default")
{
MessageBox.Show(resultObjX86.ToString());
}
}
catch(Exception)
{
}
}