获取注册表值导致程序无例外地结束

本文关键字:无例外 结束 程序 注册表 获取 | 更新日期: 2023-09-27 18:09:39

我正在努力获取和设置Windows窗体中的注册表值。

我的代码是这样的:

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SmogUser");
if (((Guid)key.GetValue("DeviceId", Guid.Empty)) == Guid.Empty)
{
    Guid deviceId = Guid.NewGuid();
    key.SetValue("DeviceId", deviceId);
    key.Close();
}
else
{
    Guid deviceId = (Guid)key.GetValue("DeviceId");
}

当我第一次运行程序时,它进入if子句并设置deviceId,但是当我第二次运行时,程序没有继续运行,也没有异常。

有什么问题吗?

获取注册表值导致程序无例外地结束

我不明白为什么RegistryKey.GetValue()方法的行为是错误的,但我用这个代码修复了你的问题:

        Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SmogUser");
        if (key != null)
        {
            var value = key.GetValue("DeviceId", null) ?? Guid.Empty;
            if (Guid.Empty.Equals(value))
            {
                Guid deviceId = Guid.NewGuid();
                key.SetValue("DeviceId", deviceId);
                key.Close();
            }
            else
            {
                var deviceId = (Guid)key.GetValue("DeviceId");
            }
        }

似乎,如果你通过null作为默认值的方法不会崩溃。然后,您可以检查是否为空,并将Guid变量值设置为Guid.Empty

您正在尝试从对象转换为Guid,这是导致错误的原因。这行得通-

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SmogUser");
if ((new Guid(key.GetValue("DeviceId", Guid.Empty).ToString()) == Guid.Empty))
{
    Guid deviceId = Guid.NewGuid();
    key.SetValue("DeviceId", deviceId);
    key.Close();
}
else
{
    Guid deviceId = new Guid(key.GetValue("DeviceId").ToString());
}

基本上我转换到字符串,然后从字符串创建一个新的Guid对象。第二次直接从object强制转换为Guid不能工作,因为返回的是Guid字符串值。

至于没有抛出异常的问题,这发生在64位的Visual Studio上,参见其他关于同一主题的帖子-

Visual Studio 2010调试器不再在错误处停止在64位Windows版本的WinForms应用程序中,VS2010没有显示未处理的异常消息

最好的解决方案是在代码周围设置一个try-catch

key.GetValue("DeviceId", Guid.Empty)的第二个参数中传递默认值为Guid.Empty,然后将其与Guid.Empty进行比较。

第一次没有密钥时,返回Guid.Empty,输入if块。然后返回另一个值(DeviceId),然后输入else

考虑msdn中关于RegistryKey.GetValue参数的信息。签名为

public Object GetValue(
    string name,
    Object defaultValue)

RegistryKey。CreateSubKey将"创建一个新的子密钥或打开一个现有的子密钥。"

您可以看到,当注册表中没有键时,将返回第二个参数。注意,注册表在程序执行之间持续存在


这里的问题是您读取注册表两次。

RegistryKey key = Registry.CurrentUser.CreateSubKey("SmogUser");
Guid regValue = Guid.Parse(key.GetValue("DeviceId", Guid.Empty).ToString());
if (value == Guid.Empty)
{
    regValue = Guid.NewGuid();
    key.SetValue("DeviceId", regValue);
    key.Close();
}
//here you have Guid in regValue, which is exactly the same
//as in registry. No need to call GetValue again